Command Line Flags in Clojure
Clojure provides a built-in clojure.tools.cli
library for parsing command-line options. We’ll use this library to implement our example command-line program.
(ns command-line-flags
(:require [clojure.tools.cli :refer [parse-opts]]
[clojure.string :as string])
(:gen-class))
(def cli-options
[["-w" "--word WORD" "a string"
:default "foo"]
["-n" "--numb NUM" "an int"
:default 42
:parse-fn #(Integer/parseInt %)
:validate [#(< 0 % 100) "Must be a number between 0 and 100"]]
["-f" "--fork" "a bool"]
["-s" "--svar SVAR" "a string var"
:default "bar"]
["-h" "--help"]])
(defn -main [& args]
(let [{:keys [options arguments errors summary]} (parse-opts args cli-options)]
(if (:help options)
(println (str "Usage:\n" summary))
(do
(println "word:" (:word options))
(println "numb:" (:numb options))
(println "fork:" (:fork options))
(println "svar:" (:svar options))
(println "tail:" (string/join " " arguments))))))
To experiment with the command-line flags program, it’s best to first compile it and then run the resulting JAR file directly.
$ lein uberjar
Try out the built program by first giving it values for all flags.
$ java -jar target/command-line-flags-0.1.0-SNAPSHOT-standalone.jar -w opt -n 7 -f -s flag
word: opt
numb: 7
fork: true
svar: flag
tail:
Note that if you omit flags they automatically take their default values.
$ java -jar target/command-line-flags-0.1.0-SNAPSHOT-standalone.jar -w opt
word: opt
numb: 42
fork: false
svar: bar
tail:
Trailing positional arguments can be provided after any flags.
$ java -jar target/command-line-flags-0.1.0-SNAPSHOT-standalone.jar -w opt a1 a2 a3
word: opt
...
tail: a1 a2 a3
Use the -h
or --help
flag to get automatically generated help text for the command-line program.
$ java -jar target/command-line-flags-0.1.0-SNAPSHOT-standalone.jar -h
Usage:
-w, --word WORD a string
-n, --numb NUM an int
-f, --fork a bool
-s, --svar SVAR a string var
-h, --help
If you provide a flag that wasn’t specified in the cli-options
, the program will print an error message.
$ java -jar target/command-line-flags-0.1.0-SNAPSHOT-standalone.jar -wat
Unknown option: "-wat"
This Clojure implementation uses the clojure.tools.cli
library to parse command-line options. It defines the options using a vector of option specifications, which includes the short and long names of each option, along with their descriptions, default values, and any parsing or validation functions.
The -main
function uses parse-opts
to process the command-line arguments, and then either prints the help message or the values of the options and any additional arguments.