Google flags ("gflags") for Clojure. See https://github.com/gflags/python-gflags.
The Google approach to command-line flags is that they are defined in the source file in which they are used. This means that in a situation with lots of code sharing, where you may have 3 or 4 command-line apps that all use one common module, the common module can define its own command line flags, which then get used by each app.
It may sound a little weird, but in practice it works well and can be very convenient.
In this translation of the concept to clojure, each namespace can define its own flags.
[com.lemonodor/gflags "0.7.3"]
Say you have a namespace for your S3 utilities. You can define some flags in that namespace for your AWS credentials etc.:
(ns s3-utils
"Utilties for accessing AWS S3."
(:require [com.lemonodor.gflags :as gflags])
...)
(gflags/define-string "aws-access-key"
nil
"The AWS access key to use.")
(gflags/define-string "aws-secret-key"
nil
"The AWS secret key to use.")
(gflags/define-integer "num-retries"
3
"The number of times to retry S3 operations.")
(defn get-s3-file [url & {:keys [access-key secret-key num-retries]}]
(let [access-key (or access-key (gflags/flags :aws-access-key))
secret-key (or secret-key (gflags/flags :aws-secret-key))]
...))
Then in a CLI app namespace, you just need to call parse-flags
:
(ns main-app
"Command-line app"
(:require [com.lemonodor.gflags :as gflags])
...)
(defn -main [& args]
(let [unparsed-args (gflags/parse-flags (into ["argv0"] args))]
...))
This code is under development (but can definitely be useful in its current state).
- Flag types:
define-string
,define-boolean
,define-integer
,define-float
,define-enum
,define-list
,define-multi-string
,define-multi-integer
,define-multi-float
. - Long names (
:name
) and short names (:short-name
). - Required flags (
:required? true
) --flagfile
- Errors if a flag with the same name is registered in two different namespaces.
--help
,--helpshort
,--helpxml
,--undefok
.- Flag serialization.
- Flag validators.
- "spaceseplist" flags.
To run tests:
$ lein test