A behaviour to define module-based commands.
A command is a keyword list (or a module implementing this behaviour) and accepts these top-level entries:
:options— option schema (seeCliMate.CLI.Option).:arguments— positional argument schema.:subcommands— a keyword list of nested commands. A command cannot declare both:argumentsand:subcommands; the first positional slot is consumed as the sub-command name. A sub-command value can be an inline keyword list, or a module implementing this behaviour.:execute— a 1-arity function called with the parsed result. Also provided via theexecute/1callback on module-based commands. When a command with:executeis selected,CliMate.CLI.parse/2returns the parsed map with an:executekey holding a zero-arity closure; calling it runs the function with the parsed map (minus the:executekey). Returnsnilwhen no execute is defined or when--helpwas requested.:name,:version,:doc— metadata used byformat_usage/2.
Option inheritance across sub-commands
Options declared on a parent command are inherited by sub-commands and can be passed on any level where the command is being parsed. Arguments given before a sub-command name are parsed with the options known at that level, and arguments given after it with the options of the sub-command, including the inherited ones.
- Redefining an option at a child level replaces the parent entry entirely,
including
:short,:default,:castand:deprecated. The child definition must keep the same:typeand:keepsettings, otherwise anArgumentErroris raised. Use:castto change the final value. - When a child option uses the same
:shortas an inherited option, the short refers to the child option after the sub-command name. The inherited option is still available with its long name. - Values given on several levels are combined as if they were given on a
single level: the last value wins,
:keeplists are concatenated and:countoccurrences are summed. - The default value, the cast function and the deprecation warning are taken from the definition of the selected sub-command, whatever the level the value was given on.
Summary
Callbacks
Returns a command definition to be used with the parser, or invoked as a sub command.
Functions
Builds a command struct from a keyword definition, or from a module implementing this behaviour.
Resolves a sub-command name given on the command line into its definition from the parent command.
Types
@type argument() :: [argument_opt()]
@type argument_opt() :: {:required, boolean()} | {:type, CliMate.CLI.Argument.vtype()} | {:doc, binary() | nil} | {:cast, nil | CliMate.CLI.Argument.caster()} | {:repeat, boolean()}
@type command() :: [command_opt()]
@type option() :: [option_opt()]
@type option_opt() :: {:doc, String.t()} | {:type, CliMate.CLI.Option.vtype()} | {:short, atom()} | {:default, term()} | {:keep, boolean()} | {:doc_arg, String.t()} | {:default_doc, String.t()} | {:cast, nil | CliMate.CLI.Option.caster()} | {:deprecated, nil | boolean() | String.t()}
Callbacks
@callback command() :: command()
Returns a command definition to be used with the parser, or invoked as a sub command.
@callback execute(CliMate.CLI.parsed()) :: term()
Functions
Builds a command struct from a keyword definition, or from a module implementing this behaviour.
The accepted entries are listed in the module documentation. Raises an
ArgumentError for invalid definitions, for instance when a command declares
both :arguments and :subcommands.
Examples
The returned struct holds the normalized options, including the automatic
:help option:
iex> command = CliMate.CLI.Command.new(name: "hello", options: [upcase: [type: :boolean]])
iex> command.name
"hello"
iex> Keyword.keys(command.options)
[:upcase, :help]
Resolves a sub-command name given on the command line into its definition from the parent command.
Returns {:ok, key, sub_command} where key is the atom form of bin_key
and sub_command is the resolved definition built with new/1. Returns
{:error, {:unknown_subcommand, bin_key}} when the name matches no declared
sub-command.