Documentation
¶
Overview ¶
Wand provides utilities for constructing command line applications from functions, with automatic parameter binding from command line arguments, environment variables and configuration files, and automatically generated help and documentation.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Cmd ¶
type Cmd struct {
// contains filtered or unexported fields
}
Cmd represents a command, a subcommand or a subcommand group.
func Args ¶
Args can be used to specify the minimum and the maximum number of positional arguments when the implementation function has variadic parameters.
func Command ¶
Command defines a command or a subcommand.
The name argument is expected to be a valid symbol, with non-leading dashes allowed (^[a-zA-Z_][a-zA-Z_0-9-]*$). It is optional to set the name of the top level command, and it is inferred from the executing binary's name. The name of the executable should also be a symbol, otherwise the automatic binding of the environment variables may not work properly.
The implementation argument needs to be a function. The input parameters of the function need to be bindable, or either an io.Reader or io.Writer. Bindable means that the type can accept scalar values, like numbers, strings, time and duration, or it has fields like a struct. Pointers to bindable types are also bindable.
Scalar arguments are considered as positional arguments of the command. Variadic arguments are supported.
The fields of struct arguments define which command line options are supported by the command. Input for the options is accepted from both command line flags or environment variables, and, if defined, from configuration. Values defined in the environment override the configuration, and values passed in as command line flags override the environment (not propagated automatically to the environment of any child processes). Zero or more struct parameters are accepted, e.g. func(g Globals, o Options).
The names of the command line flags are inferred from the struct path and field names, and are expected in kebab case with double leading dashes, unless a short form is defined. Option values are accepted both with = or just space separated following the flag. In case of bool options, omitting the value is considered as true value. Since the struct path and field names are collapsed into their flat kebab case representation, this results in ambiguity, e.g. Foo.BarBaz and Foo.Bar.Baz. In such cases, the types of the ambiguous fields must be compatible, and each such field will be bound to the same input value. Slice fields are supported, they accept zero or more options of the same name, every option value is bound as an item of the slice, e.g. --foo one --foo two --foo three.
The names of the environment variables are inferred from the struct path and field names, are prefixed with the name of the executing binary, and are expected in lower or upper snake case. E.g. for a field InputValue: FOO_BAR_INPUT_VALUE=42 /usr/bin/foo-bar. The same ambiguity rules apply as in case of the command line flags. Slice fields are supported, the values slice fields can be separated by the : character, like in case of the PATH environment variable. When necessary, the : character can be escaped as \:.
For the implementation function, zero or one io.Reader and zero or one io.Writer parameter is accepted. When present, io.Reader is populated by os.Stdin and io.Writer is populated by os.Stdout.
The implementation function can have zero or more output parameters. If the last output parameter is of type error, and the returned value is not nil, the rest of the output parameters will be ignored and the error will be printed onto os.Stderr, and the command will exit with a non zero code. In case of no error, every return value will be printed on its own line, and if a return value is a slice, then every item will also be printed on its own line. If a return value is an io.Reader, that reader will be copied onto os.Stdout. If a value is a primitive value, it will be printed onto os.Stdout using the stdlib fmt package. Complex values will be printed to os.Stdout using code.squareroundforest.org/arpio/notation.
A command can have zero or more subcommands. When executing a subcommand, the subcommands path must be at the start of the command line expression. E.g. foo bar baz --qux 42 corge, where bar is a subcommand of foo and baz is a subcommand of bar. All rules that apply to the top command, also apply to the subcommands.
If a struct field doesn't override it, a --help command line flag will be automatically injected, and calling it will display an automatically generated help. Similarly, a help subcommand is also automatically injected under every command in the command tree, if a subcommand has not already taken the name help. The help subcommand has the same effect as the --help flag. When the user provides invalid input, the command exits with a non zero code, and displays a short suggestion to the user on how to display this help.
The automatically generated help can display the command synopsis and the possible args and options, but it will not contain any descriptions. Wand is meant to be used together with docreflect, which can extract the godoc documentation of the implementation function during development time, and compile it into the final binary. When done so, the automatically generated help will include the godocs of the implementation function and the description of the fields that serve as the command line options. It is also possible to generate man pages or markdown from the godoc documentation. For more details, see the documentation of the wand tool.
When executing a command, there are two distinct stages of validation. The first one validates that the command definition itself is valid, while the second stage validates the user input against the command definition. The validation of the command definition happens without considering the user input, and errors are prefixed with "program error:". This way we can know during development time if the command definition is valid or not.
func Group ¶
Group is like command but without implementation. It is used to group subcommands. It must have at least one subcommand. Optionally, one of the subcommands can be set as the default. When a default is set, and calling the group without specifying a subcommand, the default subcommand will be executed.
func ShortForm ¶
ShortForm can be used to define short-form flags for command line options. E.g: ShortForm(cmd, "f", "foo", "b", "bar", "z", "baz"). In which case the resulting command can be called as: my-command -f one -b two -z three. If say the Foo and Bar fields are of type boolean, then the flags can be grouped as: my-command -fbz three. The defined short forms apply to the entire command tree represented by the cmd parameter.
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config represents one or more configuration sources.
func ConfigFile ¶
ConfigFile defines a configuration file source. Configuration files, when defined, are used in the entire execution scope, regardless of which subcommand is called, and the subcommands interpret only those config file fields that apply to them.
The configuration files are expected to use the ini file format, e.g values like foo_bar = 42 on separate lines. Repeated values are interpreted as distinct values for slice fields. Multiple config files are merged, such that value definitions in the config files with the higher index override the value definitions in the config files with lower indices. Discarding a value in a lower definition can be done with setting the key without a value, e.g: foo_bar. The formal definition of the used ini file format can be found here: ./ini.treerack.
When a configuration file is not marked as optional with the OptionalConfig() function, it is expected to be provided by the user.
Instead of using the static ConfigFile(name) definition, consider one or more of the dynamic definitions: Etc(), UserConfig(), ConfigFromOption() or SystemConfig().
func ConfigFromOption ¶
func ConfigFromOption() Config
ConfigFromOption defines zero or more optional config files provided by the command line option --config. When used, multiple such config files can be specified by the user.
func Etc ¶
func Etc() Config
Etc defines an optional system wide configuration file found at /etc/<name of the binary>/config.
func MergeConfig ¶
MergeConfig merges multiple configuration definitions.
func OptionalConfig ¶
OptionalConfig marks a configuration file definition as optional. Without it, the configuration is expected to be present during the execution of the command.
func SystemConfig ¶
func SystemConfig() Config
SystemConfig defines a typical set of optional configuration files, merging the Etc(), UserConfig() and ConfigFromOption() definitions.
func UserConfig ¶
func UserConfig() Config
UserConfig defines an optional user specific config file found at ~/.<name of the binary>/config or ~/.config/<name of the binary>/config.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
wand
command
|
|
|
internal
|
|
|
script/docreflect
command
|
|
|
script/ini-parser
command
|
|
|
script/man
command
|
|
|
script/markdown
command
|
|
|
tests/testlib/cmd
command
|
|
|
Package tools provides tools to work with the wand library.
|
Package tools provides tools to work with the wand library. |