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
).
See _cli_format
.
Most of the time, the only thing you'll need from this namespace is
defmain
. 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`). See [[_cli_format]]. Most of the time, the only thing you'll need from this namespace is [[defmain]]. See the [[trident.build]] source for some non-contrived example usage.
Build task interfaces are defined using a cli
object. Example:
(defn hello
"Give a friendly greeting."
[{:keys [capitalize]} the-name]
(println "Hello," (cond-> the-name capitalize clojure.string/capitalize)))
(def options {:capitalize ["-c" nil "Capitalize the name"]
:foo ["-x" "FOO" "Stores an argument in `:foo`."]})
(def cli {:fn #'hello
:prog "clj -m hello"
:options options
:option-keys [:capitalize]})
(defmain 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: clj -m hello [options]
Give a friendly greeting.
Options:
-c, --capitalize Capitalize the name
--edn EDN Additional options. Overrides CLI options.
-h, --help
0 ; 0 is the return value/exit code.
=> (with-no-shutdown (-main "--capitalize" "alice"))
Hello, Alice
0
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"})
Options are defined like this so that they can be easily reused by other build tasks.
cli
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
output.
If :desc
is omitted and :fn
is a var, this will be derived from the
function's docstring.
:options
: see above.
:option-keys
: a seq of keys in the :options
map This defines which
options are actually used for this command. --edn
and --help
options
will be added automatically unless :fn
does its own CLI processing.
See validate-args
and cli-processing?
.
: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 cli
maps. If :fn
is omitted,
dispatch
will treat the first argument as a key in :subcommands
and continue dispatching recursively.
: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 ...]]"
.
:cli-processing?
: see cli-processing?
.
See the [[trident.build]] source for some more in-depth examples.
Reusing build tasks
You can use build tasks that aren't defined with trident.cli
. Example:
(ns some.ns.pom)
(defn -main
"Some pom task"
[& args]
(when (= (first args) "--help")
(println "hello"))
(System/exit 0))
...
(ns your.ns
(:require [trident.cli :refer [defmain]]
[trident.cli.util :refer [with-no-shutdown]]))
; For convenience, `#'some.ns.pom/-main` is the same as
; `{:fn #'some.ns.pom/-main}`.
(def cli {:subcommands {"pom" #'some.ns.pom/-main
"jar" #'some.ns.jar/-main}})
(defmain cli)
=> (with-no-shutdown (-main "--help"))
Usage: <program> [options] <subcommand> [<args>]
Options:
-h, --help
Subcommands:
pom Some pom task
jar Some jar task
See `<program> <subcommand> --help` to read about a specific subcommand.
0
=> (with-no-shutdown (-main "pom" "--help"))
hello
0
Build task interfaces are defined using a `cli` object. Example: ``` (defn hello "Give a friendly greeting." [{:keys [capitalize]} the-name] (println "Hello," (cond-> the-name capitalize clojure.string/capitalize))) (def options {:capitalize ["-c" nil "Capitalize the name"] :foo ["-x" "FOO" "Stores an argument in `:foo`."]}) (def cli {:fn #'hello :prog "clj -m hello" :options options :option-keys [:capitalize]}) (defmain 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: clj -m hello [options] Give a friendly greeting. Options: -c, --capitalize Capitalize the name --edn EDN Additional options. Overrides CLI options. -h, --help 0 ; 0 is the return value/exit code. => (with-no-shutdown (-main "--capitalize" "alice")) Hello, Alice 0 ``` `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"}) ``` Options are defined like this so that they can be easily reused by other build tasks. `cli` 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` output. If `:desc` is omitted and `:fn` is a var, this will be derived from the function's docstring. - `:options`: see above. - `:option-keys`: a seq of keys in the `:options` map This defines which options are actually used for this command. `--edn` and `--help` options will be added automatically unless `:fn` does its own CLI processing. See [[validate-args]] and [[cli-processing?]]. - `: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 `cli` maps. If `:fn` is omitted, [[dispatch]] will treat the first argument as a key in `:subcommands` and continue dispatching recursively. - `: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 ...]]"`. - `:cli-processing?`: see [[cli-processing?]]. See the [[trident.build]] source for some more in-depth examples. **Reusing build tasks** You can use build tasks that aren't defined with `trident.cli`. Example: ``` (ns some.ns.pom) (defn -main "Some pom task" [& args] (when (= (first args) "--help") (println "hello")) (System/exit 0)) ... (ns your.ns (:require [trident.cli :refer [defmain]] [trident.cli.util :refer [with-no-shutdown]])) ; For convenience, `#'some.ns.pom/-main` is the same as ; `{:fn #'some.ns.pom/-main}`. (def cli {:subcommands {"pom" #'some.ns.pom/-main "jar" #'some.ns.jar/-main}}) (defmain cli) => (with-no-shutdown (-main "--help")) Usage: <program> [options] <subcommand> [<args>] Options: -h, --help Subcommands: pom Some pom task jar Some jar task See `<program> <subcommand> --help` to read about a specific subcommand. 0 => (with-no-shutdown (-main "pom" "--help")) hello 0 ```
(cli-processing? cli)
Returns true if arguments should be parsed before passing them to (:fn cli)
.
Parsing is disabled if :fn
is specified but :option-keys
and :config
aren't. This can be overridden by setting :cli-processing?
.
Returns true if arguments should be parsed before passing them to `(:fn cli)`. Parsing is disabled if `:fn` is specified but `:option-keys` and `:config` aren't. This can be overridden by setting `:cli-processing?`.
(defmain cli)
Defines -main
as an entry point for cli
.
cli
's --help
output is used as the docstring. See _cli_format
, help
and main-fn
.
Defines `-main` as an entry point for `cli`. `cli`'s `--help` output is used as the docstring. See [[_cli_format]], [[help]] and [[main-fn]].
(description cli)
Returns cli
's description as a seq of lines.
The description will be derived from cli's fn's docstring if :desc
isn't
present.
Returns `cli`'s description as a seq of lines. The description will be derived from cli's fn's docstring if `:desc` isn't present.
(dispatch cli args)
Parses args
and calls the function or subcommand specified by 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 or subcommand specified by `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.
(help cli)
Returns the --help
output for cli
.
Returns nil if cli
's function does its own CLI processing. See
cli-processing?
.
Returns the `--help` output for `cli`. Returns nil if `cli`'s function does its own CLI processing. See [[cli-processing?]].
(main-fn cli)
Returns a function suitable for binding to -main
.
Calls through to dispatch
and passes the return value to System/exit
.
Returns a function suitable for binding to `-main`. Calls through to [[dispatch]] and passes the return value to `System/exit`.
(usage {:keys [subcommands args-spec config prog] :as cli} summary)
Returns a usage string.
summary
is returned from clojure.tools.cli/parse-opts
.
Returns a usage string. `summary` is returned from `clojure.tools.cli/parse-opts`.
(validate-args {:keys [options option-keys config subcommands] :as cli} args)
Parses args
using clojure.tools.cli/parse-opts
.
Adds --edn
and --help
opts. --edn
is similar to the clj -Sdeps <EDN>
option. Returns a map that includes either :opts
and :args
OR :code
and
:exit-msg
.
Parses `args` using `clojure.tools.cli/parse-opts`. Adds `--edn` and `--help` opts. `--edn` is similar to the `clj -Sdeps <EDN>` option. Returns a map that includes either `:opts` and `:args` OR `:code` and `:exit-msg`.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close