Data-driven argument parsing library for complex Clojure CLIs.
cli-matic builds on clojure.tools.cli to take the grunt work out of building complex CLIs with nested subcommands, like you'll find in git and aws-cli.
Coming soon. This project is very new and the API could still change.
cli-matic parses CLI arguments according to a "cli-spec" map, which should be somewhat familiar to anyone who has used clojure.tools.cli:
(def git-cli-spec
{:summary "The stupid content tracker"
:base-command "git"
:usage "[<options>] <command>"
:options [[nil "--git-dir <path>" "Set the path to the repository (\".git\" directory)"]
["-v" "--version"]]
:subcommands {"commit"
{:summary "Record changes to the repository"
:usage "[<options>] [--] [<pathspec> ...]"
:options [[nil "--author <author>" "Override the commit author"]
["-p" "--patch" "Use interactive patch selection interface"]]}}})
With this map in place, we can now parse arguments (as they would be
passed to a -main
function):
(require '[cli-matic.core :as cli])
;; $ git
(cli/validate-args [] git-cli-spec)
;; => {:command [], :options {}, :arguments []}
;; $ git commit
(cli/validate-args ["commit"] git-cli-spec)
;; => {:command ["commit"], :options {}, :arguments []}
;; $ git commit -p --author [email protected]
(cli/validate-args ["commit" "-p" "--author" "[email protected]"] git-cli-spec)
;; => {:command ["commit"], :options {:patch true, :author "[email protected]"}, :arguments []}
;; $ git lost
(-> (cli/validate-args ["lost"] git-cli-spec)
:exit-message
print)
;; out> The following errors occurred while parsing your command:
;; out>
;; out> Unknown command: 'lost'
;; out>
;; out> Commands:
;; out> commit Record changes to the repository
n.b. the command your program should subsequently invoke is denoted by
a map of strings, with the root command specified by []
. This
allows us to nest commands arbitrarily deeply, representing something
like aws-cli's aws iam add-role-to-instance-profile
with ["iam" "add-role-to-instance-profile"]
.
After checking for errors (via :exit-message
), you can then dispatch
based on the returned :command
value via case
, defmulti
, or any
other means.
Sequential argument validation is left to the caller to allow full flexibility.
The :summary
, :base-command
, and :usage
entries are used solely
for documentation.
To run the test suite, run:
clojure -X:test
Use the try
alias to try out cli-matic's parsing from the
command-line against a sample specification.
clojure -M:try your --commands here
Copyright © CollBox Inc., 2022
Distributed under the MIT License.