mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 08:38:29 +00:00
259 lines
12 KiB
Go
259 lines
12 KiB
Go
|
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
/*
|
||
|
Package flags provides an extensive command line option parser.
|
||
|
The flags package is similar in functionality to the go built-in flag package
|
||
|
but provides more options and uses reflection to provide a convenient and
|
||
|
succinct way of specifying command line options.
|
||
|
|
||
|
|
||
|
Supported features
|
||
|
|
||
|
The following features are supported in go-flags:
|
||
|
|
||
|
Options with short names (-v)
|
||
|
Options with long names (--verbose)
|
||
|
Options with and without arguments (bool v.s. other type)
|
||
|
Options with optional arguments and default values
|
||
|
Option default values from ENVIRONMENT_VARIABLES, including slice and map values
|
||
|
Multiple option groups each containing a set of options
|
||
|
Generate and print well-formatted help message
|
||
|
Passing remaining command line arguments after -- (optional)
|
||
|
Ignoring unknown command line options (optional)
|
||
|
Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
|
||
|
Supports multiple short options -aux
|
||
|
Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
|
||
|
Supports same option multiple times (can store in slice or last option counts)
|
||
|
Supports maps
|
||
|
Supports function callbacks
|
||
|
Supports namespaces for (nested) option groups
|
||
|
|
||
|
Additional features specific to Windows:
|
||
|
Options with short names (/v)
|
||
|
Options with long names (/verbose)
|
||
|
Windows-style options with arguments use a colon as the delimiter
|
||
|
Modify generated help message with Windows-style / options
|
||
|
Windows style options can be disabled at build time using the "forceposix"
|
||
|
build tag
|
||
|
|
||
|
|
||
|
Basic usage
|
||
|
|
||
|
The flags package uses structs, reflection and struct field tags
|
||
|
to allow users to specify command line options. This results in very simple
|
||
|
and concise specification of your application options. For example:
|
||
|
|
||
|
type Options struct {
|
||
|
Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
|
||
|
}
|
||
|
|
||
|
This specifies one option with a short name -v and a long name --verbose.
|
||
|
When either -v or --verbose is found on the command line, a 'true' value
|
||
|
will be appended to the Verbose field. e.g. when specifying -vvv, the
|
||
|
resulting value of Verbose will be {[true, true, true]}.
|
||
|
|
||
|
Slice options work exactly the same as primitive type options, except that
|
||
|
whenever the option is encountered, a value is appended to the slice.
|
||
|
|
||
|
Map options from string to primitive type are also supported. On the command
|
||
|
line, you specify the value for such an option as key:value. For example
|
||
|
|
||
|
type Options struct {
|
||
|
AuthorInfo string[string] `short:"a"`
|
||
|
}
|
||
|
|
||
|
Then, the AuthorInfo map can be filled with something like
|
||
|
-a name:Jesse -a "surname:van den Kieboom".
|
||
|
|
||
|
Finally, for full control over the conversion between command line argument
|
||
|
values and options, user defined types can choose to implement the Marshaler
|
||
|
and Unmarshaler interfaces.
|
||
|
|
||
|
|
||
|
Available field tags
|
||
|
|
||
|
The following is a list of tags for struct fields supported by go-flags:
|
||
|
|
||
|
short: the short name of the option (single character)
|
||
|
long: the long name of the option
|
||
|
required: if non empty, makes the option required to appear on the command
|
||
|
line. If a required option is not present, the parser will
|
||
|
return ErrRequired (optional)
|
||
|
description: the description of the option (optional)
|
||
|
long-description: the long description of the option. Currently only
|
||
|
displayed in generated man pages (optional)
|
||
|
no-flag: if non-empty, this field is ignored as an option (optional)
|
||
|
|
||
|
optional: if non-empty, makes the argument of the option optional. When an
|
||
|
argument is optional it can only be specified using
|
||
|
--option=argument (optional)
|
||
|
optional-value: the value of an optional option when the option occurs
|
||
|
without an argument. This tag can be specified multiple
|
||
|
times in the case of maps or slices (optional)
|
||
|
default: the default value of an option. This tag can be specified
|
||
|
multiple times in the case of slices or maps (optional)
|
||
|
default-mask: when specified, this value will be displayed in the help
|
||
|
instead of the actual default value. This is useful
|
||
|
mostly for hiding otherwise sensitive information from
|
||
|
showing up in the help. If default-mask takes the special
|
||
|
value "-", then no default value will be shown at all
|
||
|
(optional)
|
||
|
env: the default value of the option is overridden from the
|
||
|
specified environment variable, if one has been defined.
|
||
|
(optional)
|
||
|
env-delim: the 'env' default value from environment is split into
|
||
|
multiple values with the given delimiter string, use with
|
||
|
slices and maps (optional)
|
||
|
value-name: the name of the argument value (to be shown in the help)
|
||
|
(optional)
|
||
|
choice: limits the values for an option to a set of values.
|
||
|
This tag can be specified multiple times (optional)
|
||
|
hidden: if non-empty, the option is not visible in the help or man page.
|
||
|
|
||
|
base: a base (radix) used to convert strings to integer values, the
|
||
|
default base is 10 (i.e. decimal) (optional)
|
||
|
|
||
|
ini-name: the explicit ini option name (optional)
|
||
|
no-ini: if non-empty this field is ignored as an ini option
|
||
|
(optional)
|
||
|
|
||
|
group: when specified on a struct field, makes the struct
|
||
|
field a separate group with the given name (optional)
|
||
|
namespace: when specified on a group struct field, the namespace
|
||
|
gets prepended to every option's long name and
|
||
|
subgroup's namespace of this group, separated by
|
||
|
the parser's namespace delimiter (optional)
|
||
|
command: when specified on a struct field, makes the struct
|
||
|
field a (sub)command with the given name (optional)
|
||
|
subcommands-optional: when specified on a command struct field, makes
|
||
|
any subcommands of that command optional (optional)
|
||
|
alias: when specified on a command struct field, adds the
|
||
|
specified name as an alias for the command. Can be
|
||
|
be specified multiple times to add more than one
|
||
|
alias (optional)
|
||
|
positional-args: when specified on a field with a struct type,
|
||
|
uses the fields of that struct to parse remaining
|
||
|
positional command line arguments into (in order
|
||
|
of the fields). If a field has a slice type,
|
||
|
then all remaining arguments will be added to it.
|
||
|
Positional arguments are optional by default,
|
||
|
unless the "required" tag is specified together
|
||
|
with the "positional-args" tag. The "required" tag
|
||
|
can also be set on the individual rest argument
|
||
|
fields, to require only the first N positional
|
||
|
arguments. If the "required" tag is set on the
|
||
|
rest arguments slice, then its value determines
|
||
|
the minimum amount of rest arguments that needs to
|
||
|
be provided (e.g. `required:"2"`) (optional)
|
||
|
positional-arg-name: used on a field in a positional argument struct; name
|
||
|
of the positional argument placeholder to be shown in
|
||
|
the help (optional)
|
||
|
|
||
|
Either the `short:` tag or the `long:` must be specified to make the field eligible as an
|
||
|
option.
|
||
|
|
||
|
|
||
|
Option groups
|
||
|
|
||
|
Option groups are a simple way to semantically separate your options. All
|
||
|
options in a particular group are shown together in the help under the name
|
||
|
of the group. Namespaces can be used to specify option long names more
|
||
|
precisely and emphasize the options affiliation to their group.
|
||
|
|
||
|
There are currently three ways to specify option groups.
|
||
|
|
||
|
1. Use NewNamedParser specifying the various option groups.
|
||
|
2. Use AddGroup to add a group to an existing parser.
|
||
|
3. Add a struct field to the top-level options annotated with the
|
||
|
group:"group-name" tag.
|
||
|
|
||
|
|
||
|
|
||
|
Commands
|
||
|
|
||
|
The flags package also has basic support for commands. Commands are often
|
||
|
used in monolithic applications that support various commands or actions.
|
||
|
Take git for example, all of the add, commit, checkout, etc. are called
|
||
|
commands. Using commands you can easily separate multiple functions of your
|
||
|
application.
|
||
|
|
||
|
There are currently two ways to specify a command.
|
||
|
|
||
|
1. Use AddCommand on an existing parser.
|
||
|
2. Add a struct field to your options struct annotated with the
|
||
|
command:"command-name" tag.
|
||
|
|
||
|
The most common, idiomatic way to implement commands is to define a global
|
||
|
parser instance and implement each command in a separate file. These
|
||
|
command files should define a go init function which calls AddCommand on
|
||
|
the global parser.
|
||
|
|
||
|
When parsing ends and there is an active command and that command implements
|
||
|
the Commander interface, then its Execute method will be run with the
|
||
|
remaining command line arguments.
|
||
|
|
||
|
Command structs can have options which become valid to parse after the
|
||
|
command has been specified on the command line, in addition to the options
|
||
|
of all the parent commands. I.e. considering a -v flag on the parser and an
|
||
|
add command, the following are equivalent:
|
||
|
|
||
|
./app -v add
|
||
|
./app add -v
|
||
|
|
||
|
However, if the -v flag is defined on the add command, then the first of
|
||
|
the two examples above would fail since the -v flag is not defined before
|
||
|
the add command.
|
||
|
|
||
|
|
||
|
Completion
|
||
|
|
||
|
go-flags has builtin support to provide bash completion of flags, commands
|
||
|
and argument values. To use completion, the binary which uses go-flags
|
||
|
can be invoked in a special environment to list completion of the current
|
||
|
command line argument. It should be noted that this `executes` your application,
|
||
|
and it is up to the user to make sure there are no negative side effects (for
|
||
|
example from init functions).
|
||
|
|
||
|
Setting the environment variable `GO_FLAGS_COMPLETION=1` enables completion
|
||
|
by replacing the argument parsing routine with the completion routine which
|
||
|
outputs completions for the passed arguments. The basic invocation to
|
||
|
complete a set of arguments is therefore:
|
||
|
|
||
|
GO_FLAGS_COMPLETION=1 ./completion-example arg1 arg2 arg3
|
||
|
|
||
|
where `completion-example` is the binary, `arg1` and `arg2` are
|
||
|
the current arguments, and `arg3` (the last argument) is the argument
|
||
|
to be completed. If the GO_FLAGS_COMPLETION is set to "verbose", then
|
||
|
descriptions of possible completion items will also be shown, if there
|
||
|
are more than 1 completion items.
|
||
|
|
||
|
To use this with bash completion, a simple file can be written which
|
||
|
calls the binary which supports go-flags completion:
|
||
|
|
||
|
_completion_example() {
|
||
|
# All arguments except the first one
|
||
|
args=("${COMP_WORDS[@]:1:$COMP_CWORD}")
|
||
|
|
||
|
# Only split on newlines
|
||
|
local IFS=$'\n'
|
||
|
|
||
|
# Call completion (note that the first element of COMP_WORDS is
|
||
|
# the executable itself)
|
||
|
COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}"))
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
complete -F _completion_example completion-example
|
||
|
|
||
|
Completion requires the parser option PassDoubleDash and is therefore enforced if the environment variable GO_FLAGS_COMPLETION is set.
|
||
|
|
||
|
Customized completion for argument values is supported by implementing
|
||
|
the flags.Completer interface for the argument value type. An example
|
||
|
of a type which does so is the flags.Filename type, an alias of string
|
||
|
allowing simple filename completion. A slice or array argument value
|
||
|
whose element type implements flags.Completer will also be completed.
|
||
|
*/
|
||
|
package flags
|