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 also be abbreviated as a single keyword; it will be expanded into a map where 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 also be abbreviated as a single keyword; it will be expanded into a map where 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 prefix 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.
Returns the string/symbol/keyword from values.
e.g. :parse-fn #(cli-tools/best-match % #{:red :green :blue :grey})
would parse an input of red
to
:red
, or an input of b
to :blue
; z
matches nothing and returns nil, as would
g
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 prefix 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. Returns the string/symbol/keyword from values. e.g. `:parse-fn #(cli-tools/best-match % #{:red :green :blue :grey})` would parse an input of `red` to `:red`, or an input of `b` to `:blue`; `z` matches nothing and returns nil, as would `g` 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.
(command-root)
Returns a map of the root-level commands, keyed on string (the command or group name) to a command map.
A command map describes a command, group, or command/group combo:
:command - name of the command (e.g. "create"
)
:command-path - seq of commands leading to this command (e.g. ["customer" "create"]
)
:fn - If a command, symbol for function to invoked
:subs - map of string to sub-command (if a group or command/group combo)
:doc - long documentation for this command
:group-doc - long documentation for this group
:title - optional short documentation for command or group
This is useful for code that needs visibility into all available commands (such as the built-in help command).
Returns a map of the root-level commands, keyed on string (the command or group name) to a command map. A command map describes a command, group, or command/group combo: :command - name of the command (e.g. `"create"`) :command-path - seq of commands leading to this command (e.g. `["customer" "create"]`) :fn - If a command, symbol for function to invoked :subs - map of string to sub-command (if a group or command/group combo) :doc - long documentation for this command :group-doc - long documentation for this group :title - optional short documentation for command or group This is useful for code that needs visibility into all available commands (such as the built-in help command).
(default-tool-handler dispatch-options)
Default tool handler, passed the tool options. The default-tool-options
support enabling or disabling
ANSI fonts, and requesting top-level help.
This is the default for the :handler key of dispatch options.
This function is passed the dispatch options, parses the default tool options, and delegates the rest to dispatch*
.
Default tool handler, passed the tool options. The [[default-tool-options]] support enabling or disabling ANSI fonts, and requesting top-level help. This is the default for the :handler key of dispatch options. This function is passed the dispatch options, parses the default tool options, and delegates the rest to [[dispatch*]].
Default tool command line options.
Default tool command line options.
(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 dispatch-options)
Locates commands in namespaces, finds the current command (as identified by the first command line argument) and processes CLI options and arguments.
dispatch-options:
*command-line-args*
)default-tool-handler
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. :cache-dir defaults to the value of the CLI_TOOLS_CACHE_DIR environment variable, or
to the default value ~/.cli-tools-cache
. If set to nil, then caching is disabled.
The :source-dirs option is typically used with the :transformer option; the source directories are additional directories whose contents should be included by the cache digest (because the transformer reads files in those directories).
The transformer function is passed the dispatch options and the root commands map and returns
an updated commands map; typically this involves identifying additional commands and adding them
via inject-command
.
Returns nil.
Locates commands in namespaces, finds the current command (as identified by the first command line argument) and processes CLI options and arguments. dispatch-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 - :handler - function to handle tool-level options, defaults to [[default-tool-handler]] - :cache-dir (optional, string) - directory to cache data in, or nil to disable cache - :transformer (optional, function) - transforms the root command map - :source-dirs (optional, seq of strings) - additional directories related to caching 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 (optional, string) - a short string identifying the purpose of the group - :namespaces (seq of symbols, required) - identifies namespaces providing commands in the group - :groups (optional, map) - 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. :cache-dir defaults to the value of the CLI_TOOLS_CACHE_DIR environment variable, or to the default value `~/.cli-tools-cache`. If set to nil, then caching is disabled. The :source-dirs option is typically used with the :transformer option; the source directories are additional directories whose contents should be included by the cache digest (because the transformer reads files in those directories). The transformer function is passed the dispatch options and the root commands map and returns an updated commands map; typically this involves identifying additional commands and adding them via [[inject-command]]. Returns nil.
(dispatch* dispatch-options color-flag help?)
Called from a tool handler to process remaining command line arguments.
In the dispatch options map, the tool handler should have set the following:
Called from a tool handler to process remaining command line arguments. - dispatch-options - modified dispatch options - color-flag - if non-nil, enables or disables ANSI colors before dispatching - help - if true, then change the arguments to "help", to print tool help In the dispatch options map, the tool handler should have set the following: - :arguments -- seq of remaining arguments after processing tool-level options - :tool-summary -- summary of tool options (used when printing tool help).
(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.
(inject-command command-root command-path command-map)
Injects a new command into the command root; presumably one not defined via
defcommand
.
command-path - a seq of command name strings leading to the new command command-map - map that defines the command
The final term of the command path is the name of the command itself.
A command map has keys:
Injects a new command into the command root; presumably one not defined via [[defcommand]]. command-path - a seq of command name strings leading to the new command command-map - map that defines the command The final term of the command path is the name of the command itself. A command map has keys: - :fn (keyword, required) - identifies function to invoke - :doc (string, required) - long description of the command - :title (string, optional) - short description of the command
(print-errors errors)
Prints the errors for the command to *err*
.
Ex:
Error in my-tool my-command: --count is not a number
Prints the errors for the command to `*err*`. Ex: Error in my-tool my-command: --count is not a number
(read-password prompt)
(read-password prompt opts)
Reads a line of password input from the console. This will abort if there is no console, or (by default) if the input is blank.
Returns the value input, with newlines trimmed.
The prompt is a composed string that is printed before input is read; it often ends in ": ".
Input from the console is not echoed. On some platforms, the cursor may change to indicate that a password is being read (on OS X, the cursor is changed to a key),
Options:
allow-blank? - if true, do not abort if the input is a blank string.
Reads a line of password input from the console. This will abort if there is no console, or (by default) if the input is blank. Returns the value input, with newlines trimmed. The prompt is a composed string that is printed before input is read; it often ends in ": ". Input from the console is not echoed. On some platforms, the cursor may change to indicate that a password is being read (on OS X, the cursor is changed to a key), Options: allow-blank? - if true, do not abort if the input is a blank string.
(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}) ... ```
(selected-command)
Returns a map defining the selected command. This will be nil until the end of
dispatch (i.e., just before the command function is invoked). This can be used
in the implementation of commands not defined by defcommand
.
Returns a map defining the selected command. This will be nil until the end of dispatch (i.e., just before the command function is invoked). This can be used in the implementation of commands not defined by [[defcommand]].
(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.
(summarize-specs specs)
Converts a tools.cli command specification to a description of the options; this is an enhanced version of clojure.tools.cli/summarize that makes use of indentation and ANSI colors.
Returns a delay (to ensure that ANSI color enabled/disabled options are enforced).
Converts a tools.cli command specification to a description of the options; this is an enhanced version of clojure.tools.cli/summarize that makes use of indentation and ANSI colors. Returns a delay (to ensure that ANSI color enabled/disabled options are enforced).
(tool-name)
Returns the name of the command as a simple string.
Returns the name of the command as a simple string.
For use with ask
, provides responses 'yes' (true) and 'no' (false).
For use with [[ask]], provides responses 'yes' (true) and 'no' (false).
cljdoc builds & hosts documentation for Clojure/Script libraries
Ctrl+k | Jump to recent docs |
← | Move to previous article |
→ | Move to next article |
Ctrl+/ | Jump to the search field |