Prompt.Router behaviour (prompt v0.12.0)
View SourceRouter for Prompt
Simplifies defining commands, sub-commands and arguments.
Choose the module responsible for taking the command line arguments and
use Prompt.Router, otp_app: :your_app at the top.
Then simply define your commands and arguments.
Exposes a main/1 function that is called with the command line args. It
runs the matching command and halts the VM with the command's exit code.
Exposes a run/1 function that does the same but returns the exit code
instead of halting, which is what you want in tests:
assert My.CLI.run(["checkout", "--branch", "dev"]) == 0To have main/1 return the exit code too, for example when it is called
from a release or a Mix task, use use Prompt.Router, otp_app: :my_app, halt: false.
Arguments
See arg/3
Help
help/0 prints, in order of priority, the help: option given to
use Prompt.Router, this module's @moduledoc, or usage generated from the
commands. command --help prints the command module's @moduledoc (when
available) followed by generated usage. Override help/0 or
command_help/1 to change this.
--help output goes to stdout and exits 0. When parsing fails, the reason
and the generated usage of the command go to stderr and the exit code is 1.
Distributing as an escript
Escripts strip documentation chunks by default, so @moduledoc text is not
available at runtime. Add strip_beams: [keep: ["Docs"]] to the escript:
options in mix.exs if you want moduledoc text in help. It is needed only
for that: generated usage and the help: option work without it.
Example
defmodule My.CLI do
use Prompt.Router, otp_app: :my_app
command :checkout, My.CheckoutCommand do
arg :help, :boolean
arg :branch, :string, short: :b, default: "main"
end
command "", My.DefaultCommand do
arg :info, :boolean
end
end
defmodule My.CheckoutCommand do
use Prompt.Command
@impl true
def process(arguments) do
# arguments will be a map of the defined arguments and their values
# from the command line input
# If someone used the command and passed `--branch feature/test`, then
# `argmuments would look like `%{help: false, branch: "feature/test"}`
display("checking out " <> arguments.branch)
end
end
defmodule My.DefaultCommand do
use Prompt.Command
@impl true
def init(arguments) do
# you can implement the `c:init/1` callback to transform
# the arguments before `c:process/1` is called if you want
arguments
end
@impl true
def process(arguments) do
# arguments will have a key of `:leftover` for anything
# passed to the command that doesn't have a `arg` defined.
# If someone called this with `--info --test something`, then
# arguments will look like `%{info: true, leftover: ["something", "--test"]}`:
# unused positional values first, then unknown flags as typed
display("showing info")
end
end
Summary
Callbacks
Prints the usage of one command to the screen when --help is passed after
it. The default prints the command module's @moduledoc when docs are
available, then the generated usage.
Called when the flag --completions string is passed on the command-line.
This function is called after a command is done.
Prints help to stdout when --help is passed as an argument.
Prints the error reason and the router usage to stderr, for example when no command matches and there is no fallback command.
The entry point for an escript or release. Calls run/1 with the command
line args and then halts the VM with the returned exit code.
Filters and calls the correct command module based on command line input and
returns the exit code (see handle_exit_value/1). It never halts the VM,
which makes it the function to call from tests.
Prints the version from the projects mix.exs file
Functions
Defines the arguments of a command.
Declares a command.
Declares a positional argument of a command.
Callbacks
@callback command_help(Prompt.Router.CommandSpec.t()) :: non_neg_integer()
Prints the usage of one command to the screen when --help is passed after
it. The default prints the command module's @moduledoc when docs are
available, then the generated usage.
Overridable
@callback generate_completions(binary()) :: non_neg_integer()
Called when the flag --completions string is passed on the command-line.
The default behaviour for this is to write the completion script to the screen.
zsh, bash and fish are supported out of the box. For other shells, this callback will need to be implemented.
see https://github.com/zsh-users/zsh-completions/blob/master/zsh-completions-howto.org
Overrideable
@callback handle_exit_value(any()) :: non_neg_integer()
This function is called after a command is done.
It does it's best to handle any value returned from a command and turn
it into an integer, 0 being a successful command and any non-zero being
an error. It returns the code and does not halt, main/1 does that.
An {:error, reason} prints the reason to stderr and results in 1.
Overrideable
@callback help() :: non_neg_integer()
Prints help to stdout when --help is passed as an argument.
Overridable
@callback help(String.t()) :: non_neg_integer()
Prints the error reason and the router usage to stderr, for example when no command matches and there is no fallback command.
Overridable
@callback main([binary()]) :: no_return() | non_neg_integer()
The entry point for an escript or release. Calls run/1 with the command
line args and then halts the VM with the returned exit code.
If the router was defined with use Prompt.Router, halt: false, it returns
the exit code instead of halting.
@callback run([binary()]) :: non_neg_integer()
Filters and calls the correct command module based on command line input and
returns the exit code (see handle_exit_value/1). It never halts the VM,
which makes it the function to call from tests.
@callback version() :: non_neg_integer()
Prints the version from the projects mix.exs file
Overridable
Functions
Defines the arguments of a command.
Argument Name
This indicates what the user will type as the option to the sub-command. For example,
arg :print, :booleanwould allow the user to type $ your_command --print
Options
Available options are:
- default - a default value if the user doesn't use this option
- short - an optional short argument option i.e
short: :hwould all the user to type-h - required - the flag must be given
- in - a list of allowed values of the arg type, e.g. strings for
:string - doc - a description used in help
An unknown option raises at compile time.
Declares a command.
Takes an atom or string as the command name and a Prompt.Command module.
The do block may declare arg/3, positional/3, and nested command
calls. A nested command is typed after its parent, for example
app accounts add.
Without a module, command name do ... end declares a group: a command
that only holds nested commands. Its block may contain only command calls.
command :categories do
command :add, My.AddCategory do
positional :name, :string, required: true
end
command :list, My.ListCategories
end
Declares a positional argument of a command.
Options
- required - the argument must be given
- multiple - collects all remaining values, only allowed on the last positional
- in - a list of allowed values of the arg type, e.g. strings for
:string - doc - a description used in help