Tools for wrapping build tasks in CLIs.
Like cli-matic
, this provides a higher-level wrapper over
clojure.tools.cli
. However, trident.cli
is designed specifically for
making build tasks easily reusable (including tasks not defined using
trident.cli
).
Most of the time you will need only make-cli
. See the trident.build
source for some non-contrived example usage.
Tools for wrapping build tasks in CLIs. Like `cli-matic`, this provides a higher-level wrapper over `clojure.tools.cli`. However, `trident.cli` is designed specifically for making build tasks easily reusable (including tasks not defined using `trident.cli`). Most of the time you will need only [[make-cli]]. See the [[trident.build]] source for some non-contrived example usage.
(dispatch cli args)
Parses args
and calls the function specified by cli
.
If cli
contains :fn
but not :cli-options
, dispatch
will pass args
to :fn
without parsing them first. See expand-cli
for complete
information about the format of cli
.
Returns an integer exit code. If the dispatched function returns an integer,
that will be the exit code, otherwise it will be 0. If System/exit
is called
during execution, dispatch
will disable the call and return the exit code.
Calls to shutdown-agents
will also be disabled.
Parses `args` and calls the function specified by `cli`. If `cli` contains `:fn` but not `:cli-options`, `dispatch` will pass `args` to `:fn` without parsing them first. See [[expand-cli]] for complete information about the format of `cli`. Returns an integer exit code. If the dispatched function returns an integer, that will be the exit code, otherwise it will be 0. If `System/exit` is called during execution, `dispatch` will disable the call and return the exit code. Calls to `shutdown-agents` will also be disabled.
(expand-cli compact-cli)
(expand-cli compact-cli options)
Returns an expanded form of compact-cli
, suitable for dispatch
.
options
are the same as described in clojure.tools.cli/parse-opts
except
that the long option is defined as a key in the map, not as the second
argument in the vector. Instead of writing:
(def options [["-f" "--foo FOO" "The foo"]
["-b" "--bar" "Toggle the bar"]])
You would write:
(def options {:foo ["-f" "FOO" "The foo"]
:bar ["-b" nil "Toggle the bar"})
compact-cli
is a map that can have the following keys:
:fn
: a function or function var. If present, dispatch
will apply this
function to the parsed options and any remaining arguments, as returned by
clojure.tools.cli/parse-opts
. If not present, :subcommands
must be
present.
:desc
: a seq of strings describing this task, used in the --help
documentation output. If :desc
is omitted and :fn
is a var, this will
be derived from the function's docstring.
:cli-options
: a seq of keys in options
. This will be replaced with a
value in the format specified by parse-opts
. If :cli-options
is
present, --help
and --edn
options will also be added. --edn
is
similar to the clj -Sdeps <EDN>
option.
:config
: a seq of filenames. If any of the files exist, their contents
will be read as EDN and merged (in the order given) with the results of
parse-opts
. Config files will override default option values but will
be overridden by any explicitly provided CLI options. Config files can
contain keys not included in the CLI options.
:subcommands
: a map from strings to more compact-cli
maps. If :fn
is
omitted, dispatch
will treat the first non-option argument as a key in
:subcommands
and continue dispatching recursively. expand-cli
will
also recursively expand the values of :subcommands
.
:prog
: text to use for the program name in the "Usage: ..." line in
--help
output, e.g. "clj -m my.namespace"
.
:args-spec
: a specification of the non-option arguments to use in the
"Usage: ..." line in --help
output, e.g. "[foo1 [foo2 ...]]"
.
Reusing build tasks
For convenience, compact-cli
can be a function or function var instead of a
map. In this case, it will be replaced with {:fn <fn>}
. This can be
useful for curating build tasks as subcommands, especially build tasks not
defined with trident.cli
. For example:
(expand-cli {:subcommands {"pom" #'some.ns.pom/-main
"jar" #'some.ns.jar/-main}})
Since the subcommands are vars, the --help
option output will include the
first line of their docstrings. (If the functions don't have docstrings,
you can always use the map form for compact-cli
and include :desc
yourself).
Since make-cli
returns the expanded cli
map, you can reuse it:
(expand-cli
{:subcommands
(merge
; Regular build tasks, not defined with trident.build
{"pom" #'some.ns.pom/-main
"jar" #'some.ns.jar/-main}
(:subcommands some.ns.deploy/cli))})) ; `cli` defined with `make-cli`
expand-cli
is idempotent, so it's safe to give it CLI maps that have already
been expanded.
Returns an expanded form of `compact-cli`, suitable for [[dispatch]]. `options` are the same as described in `clojure.tools.cli/parse-opts` except that the long option is defined as a key in the map, not as the second argument in the vector. Instead of writing: ``` (def options [["-f" "--foo FOO" "The foo"] ["-b" "--bar" "Toggle the bar"]]) ``` You would write: ``` (def options {:foo ["-f" "FOO" "The foo"] :bar ["-b" nil "Toggle the bar"}) ``` `compact-cli` is a map that can have the following keys: - `:fn`: a function or function var. If present, [[dispatch]] will apply this function to the parsed options and any remaining arguments, as returned by `clojure.tools.cli/parse-opts`. If not present, `:subcommands` must be present. - `:desc`: a seq of strings describing this task, used in the `--help` documentation output. If `:desc` is omitted and `:fn` is a var, this will be derived from the function's docstring. - `:cli-options`: a seq of keys in `options`. This will be replaced with a value in the format specified by `parse-opts`. If `:cli-options` is present, `--help` and `--edn` options will also be added. `--edn` is similar to the `clj -Sdeps <EDN>` option. - `:config`: a seq of filenames. If any of the files exist, their contents will be read as EDN and merged (in the order given) with the results of `parse-opts`. Config files will override default option values but will be overridden by any explicitly provided CLI options. Config files can contain keys not included in the CLI options. - `:subcommands`: a map from strings to more `compact-cli` maps. If `:fn` is omitted, [[dispatch]] will treat the first non-option argument as a key in `:subcommands` and continue dispatching recursively. [[expand-cli]] will also recursively expand the values of `:subcommands`. - `:prog`: text to use for the program name in the "Usage: ..." line in `--help` output, e.g. `"clj -m my.namespace"`. - `:args-spec`: a specification of the non-option arguments to use in the "Usage: ..." line in `--help` output, e.g. `"[foo1 [foo2 ...]]"`. **Reusing build tasks** For convenience, `compact-cli` can be a function or function var instead of a map. In this case, it will be replaced with `{:fn <fn>}`. This can be useful for curating build tasks as subcommands, especially build tasks not defined with `trident.cli`. For example: ``` (expand-cli {:subcommands {"pom" #'some.ns.pom/-main "jar" #'some.ns.jar/-main}}) ``` Since the subcommands are vars, the `--help` option output will include the first line of their docstrings. (If the functions don't have docstrings, you can always use the map form for `compact-cli` and include `:desc` yourself). Since `make-cli` returns the expanded `cli` map, you can reuse it: ``` (expand-cli {:subcommands (merge ; Regular build tasks, not defined with trident.build {"pom" #'some.ns.pom/-main "jar" #'some.ns.jar/-main} (:subcommands some.ns.deploy/cli))})) ; `cli` defined with `make-cli` ``` `expand-cli` is idempotent, so it's safe to give it CLI maps that have already been expanded.
(main-fn cli)
Returns a function suitable for binding to -main
. See make-cli
.
Returns a function suitable for binding to `-main`. See [[make-cli]].
(make-cli compact-cli)
(make-cli compact-cli options)
Returns a map with the keys :cli
, :main-fn
and :help
.
cli
: an expanded form of compact-cli
and options
, suitable for passing to
dispatch
. See expand-cli
for the format of compact-cli
and options
,
including tips about how to reuse other build tasks.
main-fn
: a function suitable for binding to -main
. It will call
dispatch
, afterwards calling System/exit
with the function's return
value (if it's an integer) as the exit code.
help
: the auto-generated --help
output for this task. Good for including in
-main
's docstring.
Example:
(defn hello
"Give a friendly greeting."
[{:keys [capitalize]} the-name]
(println "Hello," (cond-> the-name capitalize clojure.string/capitalize)))
(def compact-cli {:fn #'hello
:cli-options [:capitalize]})
(def options {:capitalize ["-c" nil "Capitalize the name"]})
(let [{:keys [cli main-fn help]} (make-cli compact-cli options)]
(def ^{:doc help} -main main-fn)
; `cli` is exposed so it can be reused if needed.
(def cli cli))
; Normally `main-fn` will shutdown the JVM, but we can prevent this using
; `trident.cli.util/with-no-shutdown`:
=> (with-no-shutdown (-main "--help"))
Usage: <program> [options]
Give a friendly greeting.
Options:
-c, --capitalize Capitalize the name
-h, --help
0 ; 0 is the return value/exit code.
=> (with-no-shutdown (-main "--capitalize" "alice"))
Hello, Alice
0
Returns a map with the keys `:cli`, `:main-fn` and `:help`. `cli`: an expanded form of `compact-cli` and `options`, suitable for passing to [[dispatch]]. See [[expand-cli]] for the format of `compact-cli` and `options`, including tips about how to reuse other build tasks. `main-fn`: a function suitable for binding to `-main`. It will call [[dispatch]], afterwards calling `System/exit` with the function's return value (if it's an integer) as the exit code. `help`: the auto-generated `--help` output for this task. Good for including in `-main`'s docstring. Example: ``` (defn hello "Give a friendly greeting." [{:keys [capitalize]} the-name] (println "Hello," (cond-> the-name capitalize clojure.string/capitalize))) (def compact-cli {:fn #'hello :cli-options [:capitalize]}) (def options {:capitalize ["-c" nil "Capitalize the name"]}) (let [{:keys [cli main-fn help]} (make-cli compact-cli options)] (def ^{:doc help} -main main-fn) ; `cli` is exposed so it can be reused if needed. (def cli cli)) ; Normally `main-fn` will shutdown the JVM, but we can prevent this using ; `trident.cli.util/with-no-shutdown`: => (with-no-shutdown (-main "--help")) Usage: <program> [options] Give a friendly greeting. Options: -c, --capitalize Capitalize the name -h, --help 0 ; 0 is the return value/exit code. => (with-no-shutdown (-main "--capitalize" "alice")) Hello, Alice 0 ```
(usage {:keys [summary subcommands desc args-spec config prog] :as cli})
Returns a usage string.
summary
is returned from clojure.tools.cli/parse-opts
. See expand-cli
for the other keys.
Returns a usage string. `summary` is returned from `clojure.tools.cli/parse-opts`. See [[expand-cli]] for the other keys.
(validate-args {:keys [cli-options config subcommands] :as cli} args)
Parses args
using clojure.tools.cli/parse-opts
.
Returns a map that includes either :opts
and :args
OR :code
and
:exit-msg
.
See expand-cli
for the format of cli
.
Parses `args` using `clojure.tools.cli/parse-opts`. Returns a map that includes either `:opts` and `:args` OR `:code` and `:exit-msg`. See [[expand-cli]] for the format of `cli`.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close