This module implements command line parser. Parser operates with
commands and arguments represented as a tree. Commands
are branches, and arguments are leaves of the tree. Parser always starts with the
root command, named after
A
#!/usr/bin/env escript
main(Args) ->
argparse:run(Args, cli(), #{progname => mul}).
cli() ->
#{
arguments => [
#{name => left, type => integer},
#{name => right, type => integer}
],
handler =>
fun (#{left := Left, right := Right}) ->
io:format("~b~n", [Left * Right])
end
}.
Running this script with no arguments results in an error, accompanied by the usage information.
The
A command may contain nested commands, forming a hierarchy. Arguments
defined at the upper level command are automatically added to all nested
commands. Nested commands example (assuming
cli() ->
#{
%% top level argument applicable to all commands
arguments => [#{name => top}],
commands => #{
"first" => #{
%% argument applicable to "first" command and
%% all commands nested into "first"
arguments => [#{name => mid}],
commands => #{
"second" => #{
%% argument only applicable for "second" command
arguments => [#{name => bottom}],
handler => fun (A) -> io:format("~p~n", [A]) end
}
}
}
}
}.
In the example above, a 3-level hierarchy is defined. First is the script
itself (
./nested.erl one first second two three
#{top => "one",mid => "two",bottom => "three"}
Commands have preference over positional argument values. In the example
above, commands and positional arguments are interleaving, and
In the user input, short options may be concatenated with their values. Long
options support values separated by
cli() ->
#{
arguments => [
#{name => long, long => "-long"},
#{name => short, short => $s}
],
handler => fun (Args) -> io:format("~p~n", [Args]) end
}.
Running
Shortened option names are not supported: it is not possible to use
Defines type conversion applied to the string retrieved from the user input.
If the conversion is successful, resulting value is validated using optional
User-defined help template to print in the command usage. First element of
a tuple must be a string. It is printed as a part of the usage header. Second
element of the tuple can be either a string printed as-is, a list
containing strings,
Argument name is used to populate argument map.
Argument specification. Defines a single named argument that is returned
in the
If either of the
By default, all positional arguments must be present in the command line. The parser will return an error otherwise. Options, however, may be omitted, in which case resulting argument map will either contain the default value, or not have the key at all.
Sets the argument name in the parsed argument map. If
Defines a short (single character) form of an optional argument.
%% Define a command accepting argument named myarg, with short form $a:
1> Cmd = #{arguments => [#{name => myarg, short => $a}]}.
%% Parse command line "-a str":
2> {ok, ArgMap, _, _} = argparse:parse(["-a", "str"], Cmd), ArgMap.
#{myarg => "str"}
%% Option value can be concatenated with the switch: "-astr"
3> {ok, ArgMap, _, _} = argparse:parse(["-astr"], Cmd), ArgMap.
#{myarg => "str"}
By default all options expect a single value following the option switch. The only exception is an option of a boolean type.
Defines a long form of an optional argument.
1> Cmd = #{arguments => [#{name => myarg, long => "name"}]}.
%% Parse command line "-name Erlang":
2> {ok, ArgMap, _, _} = argparse:parse(["-name", "Erlang"], Cmd), ArgMap.
#{myarg => "Erlang"}
%% Or use "=" to separate the switch and the value:
3> {ok, ArgMap, _, _} = argparse:parse(["-name=Erlang"], Cmd), ArgMap.
#{myarg => "Erlang"}
If neither
Forces the parser to expect the argument to be present in the command line. By default, all positional argument are required, and all options are not.
Specifies the default value to put in the parsed argument map if the value is not supplied in the command line.
1> argparse:parse([], #{arguments => [#{name => myarg, short => $m}]}).
{ok,#{}, ...
2> argparse:parse([], #{arguments => [#{name => myarg, short => $m, default => "def"}]}).
{ok,#{myarg => "def"}, ...
Defines type conversion and validation routine. The default is
Defines the number of following arguments to consume from the command line. By default, the parser consumes the next argument and converts it into an Erlang term according to the specified type.
Consume exactly this number of positional arguments, fail if there is not enough. Value in the argument map contains a list of exactly this length. Example, defining a positional argument expecting 3 integer values:
1> Cmd = #{arguments => [#{name => ints, type => integer, nargs => 3}]},
argparse:parse(["1", "2", "3"], Cmd).
{ok, #{ints => [1, 2, 3]}, ...
Another example defining an option accepted as
1> Cmd = #{arguments => [#{name => env, long => "env", nargs => 2}]},
argparse:parse(["-env", "key", "value"], Cmd).
{ok, #{env => ["key", "value"]}, ...
Consume all following arguments until hitting the next option (starting with an option prefix). May result in an empty list added to the arguments map.
1> Cmd = #{arguments => [
#{name => nodes, long => "nodes", nargs => list},
#{name => verbose, short => $v, type => boolean}
]},
argparse:parse(["-nodes", "one", "two", "-v"], Cmd).
{ok, #{nodes => ["one", "two"], verbose => true}, ...
Same as
Consumes the next argument from the command line, if it does not start with an option prefix. Otherwise, adds a default value to the arguments map.
1> Cmd = #{arguments => [
#{name => level, short => $l, nargs => 'maybe', default => "error"},
#{name => verbose, short => $v, type => boolean}
]},
argparse:parse(["-l", "info", "-v"], Cmd).
{ok,#{level => "info",verbose => true}, ...
%% When "info" is omitted, argument maps receives the default "error"
2> argparse:parse(["-l", "-v"], Cmd).
{ok,#{level => "error",verbose => true}, ...
Consumes the next argument from the command line, if it does not start with an option prefix. Otherwise, adds a specified Erlang term to the arguments map.
Fold all remaining command line arguments into a list, ignoring any option prefixes or switches. Useful for proxying arguments into another command line utility.
1> Cmd = #{arguments => [
#{name => verbose, short => $v, type => boolean},
#{name => raw, long => "-", nargs => all}
]},
argparse:parse(["-v", "--", "-kernel", "arg", "opt"], Cmd).
{ok,#{raw => ["-kernel","arg","opt"],verbose => true}, ...
Defines an action to take when the argument is found in the command line. The
default action is
Store the value in the arguments map. Overwrites the value previously written.
1> Cmd = #{arguments => [#{name => str, short => $s}]},
argparse:parse(["-s", "one", "-s", "two"], Cmd).
{ok, #{str => "two"}, ...
Stores the specified term instead of reading the value from the command line.
1> Cmd = #{arguments => [#{name => str, short => $s, action => {store, "two"}}]},
argparse:parse(["-s"], Cmd).
{ok, #{str => "two"}, ...
Appends the repeating occurrences of the argument instead of overwriting.
1> Cmd = #{arguments => [#{name => node, short => $n, action => append}]},
argparse:parse(["-n", "one", "-n", "two", "-n", "three"], Cmd).
{ok, #{node => ["one", "two", "three"]}, ...
%% Always produces a list - even if there is one occurrence
2> argparse:parse(["-n", "one"], Cmd).
{ok, #{node => ["one"]}, ...
Same as
Puts a counter as a value in the arguments map. Useful for implementing verbosity option:
1> Cmd = #{arguments => [#{name => verbose, short => $v, action => count}]},
argparse:parse(["-v"], Cmd).
{ok, #{verbose => 1}, ...
2> argparse:parse(["-vvvv"], Cmd).
{ok, #{verbose => 4}, ...
Works as
1> Cmd = #{arguments => [#{name => duet, short => $d, nargs => 2, action => extend}]},
argparse:parse(["-d", "a", "b", "-d", "c", "d"], Cmd).
{ok, #{duet => ["a", "b", "c", "d"]}, ...
%% 'append' would result in {ok, #{duet => [["a", "b"],["c", "d"]]},
Specifies help/usage text for the argument.
Arguments map is the map of argument names to the values extracted from the command line. It is passed to the matching command handler. If an argument is omitted, but has the default value is specified, it is added to the map. When no default value specified, and argument is not present in the command line, corresponding key is not present in the resulting map.
Command handler specification. Called by
Function accepting
Function named
Function accepting as many arguments as there are in the
1> Cmd = #{arguments => [
#{name => x, type => float},
#{name => y, type => float, short => $p}],
handler => {fun math:pow/2, 1}},
argparse:run(["2", "-p", "3"], Cmd, #{}).
8.0
%% default term 1 is passed to math:pow/2
2> argparse:run(["2"], Cmd, #{}).
2.0
Function named
User-defined help template. Use this option to mix custom and predefined usage text. Help template may contain unicode strings, and following atoms:
Formatted command line usage text, e.g.
Expanded list of sub-commands.
Detailed description of positional arguments.
Detailed description of optional arguments.
Command specification. May contain nested commands, forming a hierarchy.
Maps of nested commands. Keys must be strings, matching command line input. Basic utilities do not need to specify any nested commands.
List of arguments accepted by this command, and all nested commands in the hierarchy.
Specifies help/usage text for this command. Pass
Specifies a callback function to call by
Path to the nested command. First element is always the
Returned from
First element is the path to the command that was considered when the
parser detected an error. Second element,
When
Use
Options changing parser behaviour.
Changes the option prefix (the default is
Specifies the default value for all optional arguments. When this field is set, resulting argument map will contain all argument names. Useful for easy pattern matching on the argument map in the handler function.
Specifies the program (root command) name. Returned as the
first element of the command path, and printed in help/usage
text. It is recommended to have this value set, otherwise the
default one is determined with
Specifies the path to the nested command for
Specifies the help/usage text width (characters) for
Returned from
Generates human-readable text for
Generates help/usage information text for the command
supplied, or any nested command when
Parses command line arguments according to the command specification.
Raises an exception if the command specification is not valid. Use
This function does not call command handler.
Parses command line arguments and calls the matching command handler. Prints human-readable error, help/usage information for the discovered command, and halts the emulator with code 1 if there is any error in the command specification or user-provided command line input.
This function is designed to work as an entry point to a standalone