Utilities for create CLIs around functions, and creating tools with multiple sub-commands.
Utilities for create CLIs around functions, and creating tools with multiple sub-commands.
(abort & message)
(abort status & message)
Invoked when a tool has a runtime failure. The messages, composed strings, are
printed to *err*
and then exit
is invoked.
By default, the exit status is 1. If the first message value is a number, it is used as the exit status instead.
Invoked when a tool has a runtime failure. The messages, composed strings, are printed to `*err*` and then [[exit]] is invoked. By default, the exit status is 1. If the first message value is a number, it is used as the exit status instead.
(ask prompt responses)
(ask prompt responses opts)
Ask the user a question with a fixed number of possible responses.
The prompt is a string (possibly, a composed string) and should usually end with a question mark.
Each response is a map with
Key | Type | Value |
---|---|---|
:label | String | Response entered by user, e.g., "yes" |
:value | any | Value to be returned by ask , e.g., true |
A response may be a keyword; the :value will be the keyword, and the label will simply be the name of the keyword.
Ex:
(ask "Are you sure?" cli/yes-or-no {:default true})
Will prompt with:
Are you sure? (yes/no)
With "yes" in bold.
The prompt is written to *err*
.
The :value is typically unique, but this is not enforced, and it can be useful to have distinct labels map to the same output value.
The user is allowed to enter a shorter input, if that shorter input
(via best-match
) uniquely identifies a label.
Options:
:default - the default value which must correspond to one value (may not be nil) :force? - if true, then the user is not prompted and the default (which must be non-nil) is returned
The default, if any, is returned when the user simply hits enter (enters a blank string).
The user input must correspond to a label; if not, a warning is printed and the user is again prompted.
Once a label is identified, ask
returns the corresponding value.
Ask the user a question with a fixed number of possible responses. The prompt is a string (possibly, a composed string) and should usually end with a question mark. Each response is a map with Key | Type | Value --- |--- |--- :label | String | Response entered by user, e.g., "yes" :value | any | Value to be returned by `ask`, e.g., true A response may be a keyword; the :value will be the keyword, and the label will simply be the name of the keyword. Ex: (ask "Are you sure?" cli/yes-or-no {:default true}) Will prompt with: Are you sure? (yes/no) With "yes" in bold. The prompt is written to `*err*`. The :value is typically unique, but this is not enforced, and it can be useful to have distinct labels map to the same output value. The user is allowed to enter a shorter input, if that shorter input (via [[best-match]]) uniquely identifies a label. Options: :default - the default value which must correspond to one value (may not be nil) :force? - if true, then the user is not prompted and the default (which must be non-nil) is returned The default, if any, is returned when the user simply hits enter (enters a blank string). The user input must correspond to a label; if not, a warning is printed and the user is again prompted. Once a label is identified, `ask` returns the corresponding value.
(best-match input values)
Given an input string and a seq of possible values, returns the matching value if it can be uniquely identified.
Values may be strings, symbols, or keywords.
best-match does a caseless substring match against the provided values. It returns the single value that matches the input. It returns nil if no value matches, or if multiple values match.
Some special handling for the -
character; the input value is split on -
and turned into
a generous regular expression that matches the substring on either side of the -
as well as the -
itself.
Returns the string/symbol/keyword from values.
e.g. :parse-fn #(cli-tools/best-match % #{:red :green :blue})
would parse an input of red
to
:red
, or an input of b
to :blue
; z
matches nothing and returns nil, as would
e
which matches multiple values.
Expects symbols and keywords to be unqualified.
Given an input string and a seq of possible values, returns the matching value if it can be uniquely identified. Values may be strings, symbols, or keywords. best-match does a caseless substring match against the provided values. It returns the single value that matches the input. It returns nil if no value matches, or if multiple values match. Some special handling for the `-` character; the input value is split on `-` and turned into a generous regular expression that matches the substring on either side of the `-` as well as the `-` itself. Returns the string/symbol/keyword from values. e.g. `:parse-fn #(cli-tools/best-match % #{:red :green :blue})` would parse an input of `red` to `:red`, or an input of `b` to `:blue`; `z` matches nothing and returns nil, as would `e` which matches multiple values. Expects symbols and keywords to be unqualified.
(command-path)
Returns a composed string of the tool name and command path that can be used
in error messages. This function requires
global data bound by dispatch*
and returns nil when invoked outside that
context.
Returns a composed string of the tool name and command path that can be used in error messages. This function requires global data bound by [[dispatch*]] and returns nil when invoked outside that context.
(defcommand fn-name docstring interface & body)
Defines a command.
A command's interface identifies how to parse command options and positional arguments, mapping them to local symbols.
Commands must always have a docstring; this is part of the -h
/ --help
summary.
The returned function is variadic, accepting a number of strings, much
like a -main
function. For testing purposes, it may instead be passed a single map,
a map of options, which bypasses parsing and validation of the arguments.
Finally, the body is evaluated inside a let that destructures the options and positional arguments into local symbols.
Defines a command. A command's _interface_ identifies how to parse command options and positional arguments, mapping them to local symbols. Commands must always have a docstring; this is part of the `-h` / `--help` summary. The returned function is variadic, accepting a number of strings, much like a `-main` function. For testing purposes, it may instead be passed a single map, a map of options, which bypasses parsing and validation of the arguments. Finally, the body is evaluated inside a let that destructures the options and positional arguments into local symbols.
(dispatch options)
Locates commands in namespaces, finds the current command (as identified by the first command line argument) and processes CLI options and arguments.
options:
*command-line-args*
)The :tool-name option is only semi-optional; in a Babashka script, it will default
from the babashka.file
system property, if any. An exception is thrown if :tool-name
is not provided and can't be defaulted.
A group map defines a set of commands grouped under a common name. Its structure:
dispatch will always add the net.lewiship.cli-tools.builtins
namespace to the root
namespace list; this ensures the built-in help
command is available.
If option and argument parsing is unsuccessful, then an error message is written to *err*, and the program exits with error code 1.
Caching is enabled by default; this means that a scan of all namespaces is only required on the first execution; subsequently, only the single namespace implementing the selected command will need to be loaded.
Returns nil.
Locates commands in namespaces, finds the current command (as identified by the first command line argument) and processes CLI options and arguments. options: - :tool-name (optional, string) - used in command summary and errors - :doc (optional, string) - used in help summary - :arguments - command line arguments to parse (defaults to `*command-line-args*`) - :namespaces - seq of symbols identifying namespaces to search for root-level commands - :groups - map of group command (a string) to a group map The :tool-name option is only semi-optional; in a Babashka script, it will default from the `babashka.file` system property, if any. An exception is thrown if :tool-name is not provided and can't be defaulted. A group map defines a set of commands grouped under a common name. Its structure: - :doc - string, a short string identifying the purpose of the group - :namespaces - seq of symbols identifying namespaces of commands in the group - :groups - recusive map of groups nested within the group dispatch will always add the `net.lewiship.cli-tools.builtins` namespace to the root namespace list; this ensures the built-in `help` command is available. If option and argument parsing is unsuccessful, then an error message is written to \*err\*, and the program exits with error code 1. Caching is enabled by default; this means that a scan of all namespaces is only required on the first execution; subsequently, only the single namespace implementing the selected command will need to be loaded. Returns nil.
(dispatch* expanded-options)
Invoked by dispatch
after namespace and command resolution.
Invoked by [[dispatch]] after namespace and command resolution.
(exit status)
An indirect call to System/exit, passing a numeric status code (0 for success, non-zero for an error).
This is provided so that, during testing, when set-prevent-exit!
has been called, the call
to exit
will instead throw an exception.
An indirect call to System/exit, passing a numeric status code (0 for success, non-zero for an error). This is provided so that, during testing, when [[set-prevent-exit!]] has been called, the call to `exit` will instead throw an exception.
(expand-dispatch-options options)
Called by dispatch
to expand the options before calling dispatch*
.
Some applications may call this instead of dispatch
, modify the results, and then
invoke dispatch*
.
Manages a cache, so the results may
Called by [[dispatch]] to expand the options before calling [[dispatch*]]. Some applications may call this instead of `dispatch`, modify the results, and then invoke `dispatch*`. Manages a cache, so the results may
(print-errors errors)
(print-errors _command-map errors)
Prints the errors for the command to *err*
.
~To invoke this, you need the command map, which is available via the :as clause to defcommand
.~
Ex:
Error in my-tool my-command: --count is not a number
errors is a seq of strings (or composed strings) to display as errors.
In 0.15.1, the two-argument variant was deprecated in favor of the new version which only requires the seq of errors.
Prints the errors for the command to `*err*`. ~To invoke this, you need the command map, which is available via the :as clause to [[defcommand]].~ Ex: Error in my-tool my-command: --count is not a number errors is a seq of strings (or composed strings) to display as errors. In 0.15.1, the two-argument variant was deprecated in favor of the new version which only requires the seq of errors.
(select-option short-opt
long-opt
desc-prefix
input-values
&
{:keys [default] :as kvs})
Builds a standard option spec for selecting from a list of possible values.
Uses best-match
to parse the user-supplied value (allowing for
reasonable abbeviations).
Following the input values is a list of key value pairs; the :default key, if non-nil, should be a member of input-values and will generate :default and :default-desc keys in the option spec.
Adds :parse-fn and :validate keys to the returned option spec, as well as :default and :default-desc. Additional key/value pairs are passed through as-is.
Usage (as part of a command's interface):
... format (select-option
"-f" "--format FORMAT" "Output format:"
#{:plain :csv :tsv :json :edn}) ...
Builds a standard option spec for selecting from a list of possible values. Uses [[best-match]] to parse the user-supplied value (allowing for reasonable abbeviations). Following the input values is a list of key value pairs; the :default key, if non-nil, should be a member of input-values and will generate :default and :default-desc keys in the option spec. Adds :parse-fn and :validate keys to the returned option spec, as well as :default and :default-desc. Additional key/value pairs are passed through as-is. Usage (as part of a command's interface): ``` ... format (select-option "-f" "--format FORMAT" "Output format:" #{:plain :csv :tsv :json :edn}) ...
(set-prevent-exit! flag)
cli-tools will call exit
when help is requested (with a 0 exit status, or 1 for
a input validation error). Normally, that results in a call to System/exit, but this function,
used for testing, allow exit
to throw an exception instead.
cli-tools will call [[exit]] when help is requested (with a 0 exit status, or 1 for a input validation error). Normally, that results in a call to System/exit, but this function, used for testing, allow [[exit]] to throw an exception instead.
(sorted-name-list values)
Converts a seq of strings, keywords, or symbols (as used with best-match
) to a comma-separated
string listing the values. This is often used with help summary or error messages.
Converts a seq of strings, keywords, or symbols (as used with [[best-match]]) to a comma-separated string listing the values. This is often used with help summary or error messages.
For use with ask
, provides responses 'yes' (true) and 'no' (false).
For use with [[ask]], provides responses 'yes' (true) and 'no' (false).
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close