Documentation
¶
Overview ¶
Package ff provides a flags-first approach to runtime configuration.
The central function is Parse, which populates a flag set from commandline arguments, environment variables, and/or config files. Parse takes either an implementation of the Flags interface, or (for compatibility reasons) a concrete flag.FlagSet. Option values can be used to control parsing behavior.
FlagSet is provided as a standard implementation of the Flags interface, inspired by getopts(3). It supports single (-f) and long (--foo) flag names.
Command is provided as a tool for building CLI applications, like docker or kubectl, in a simple and declarative style. It's intended to be easier to understand and maintain than common alternatives.
Index ¶
- Variables
- func Parse(fs FlagSetAny, args []string, options ...Option) error
- func PlainParser(r io.Reader, set func(name, value string) error) error
- type Command
- func (cmd *Command) GetParent() *Command
- func (cmd *Command) GetSelected() *Command
- func (cmd *Command) Parse(args []string, options ...Option) error
- func (cmd *Command) ParseAndRun(ctx context.Context, args []string, options ...Option) error
- func (cmd *Command) Reset() error
- func (cmd *Command) Run(ctx context.Context) error
- type ConfigFileParseFunc
- type Flag
- type FlagConfig
- type FlagSet
- func (fs *FlagSet) AddFlag(cfg FlagConfig) (Flag, error)
- func (fs *FlagSet) AddStruct(val any) error
- func (fs *FlagSet) Bool(short rune, long string, usage string) *bool
- func (fs *FlagSet) BoolConfig(cfg FlagConfig) *bool
- func (fs *FlagSet) BoolDefault(short rune, long string, def bool, usage string) *bool
- func (fs *FlagSet) BoolLong(long string, usage string) *bool
- func (fs *FlagSet) BoolLongDefault(long string, def bool, usage string) *bool
- func (fs *FlagSet) BoolShort(short rune, usage string) *bool
- func (fs *FlagSet) BoolShortDefault(short rune, def bool, usage string) *bool
- func (fs *FlagSet) BoolVar(pointer *bool, short rune, long string, usage string) Flag
- func (fs *FlagSet) BoolVarDefault(pointer *bool, short rune, long string, def bool, usage string) Flag
- func (fs *FlagSet) Duration(short rune, long string, def time.Duration, usage string) *time.Duration
- func (fs *FlagSet) DurationConfig(cfg FlagConfig, def time.Duration) *time.Duration
- func (fs *FlagSet) DurationLong(long string, def time.Duration, usage string) *time.Duration
- func (fs *FlagSet) DurationShort(short rune, def time.Duration, usage string) *time.Duration
- func (fs *FlagSet) DurationVar(pointer *time.Duration, short rune, long string, def time.Duration, ...) Flag
- func (fs *FlagSet) Float64(short rune, long string, def float64, usage string) *float64
- func (fs *FlagSet) Float64Config(cfg FlagConfig, def float64) *float64
- func (fs *FlagSet) Float64Long(long string, def float64, usage string) *float64
- func (fs *FlagSet) Float64Short(short rune, def float64, usage string) *float64
- func (fs *FlagSet) Float64Var(pointer *float64, short rune, long string, def float64, usage string) Flag
- func (fs *FlagSet) Func(short rune, long string, fn func(string) error, usage string)
- func (fs *FlagSet) FuncLong(long string, fn func(string) error, usage string)
- func (fs *FlagSet) FuncShort(short rune, fn func(string) error, usage string)
- func (fs *FlagSet) GetArgs() []string
- func (fs *FlagSet) GetFlag(name string) (Flag, bool)
- func (fs *FlagSet) GetName() string
- func (fs *FlagSet) Int(short rune, long string, def int, usage string) *int
- func (fs *FlagSet) IntConfig(cfg FlagConfig, def int) *int
- func (fs *FlagSet) IntLong(long string, def int, usage string) *int
- func (fs *FlagSet) IntShort(short rune, def int, usage string) *int
- func (fs *FlagSet) IntVar(pointer *int, short rune, long string, def int, usage string) Flag
- func (fs *FlagSet) IsParsed() bool
- func (fs *FlagSet) Parse(args []string) error
- func (fs *FlagSet) Reset() error
- func (fs *FlagSet) SetParent(parent *FlagSet) *FlagSet
- func (fs *FlagSet) String(short rune, long string, def string, usage string) *string
- func (fs *FlagSet) StringConfig(cfg FlagConfig, def string) *string
- func (fs *FlagSet) StringEnum(short rune, long string, usage string, valid ...string) *string
- func (fs *FlagSet) StringEnumLong(long string, usage string, valid ...string) *string
- func (fs *FlagSet) StringEnumShort(short rune, usage string, valid ...string) *string
- func (fs *FlagSet) StringEnumVar(pointer *string, short rune, long string, usage string, valid ...string) Flag
- func (fs *FlagSet) StringList(short rune, long string, usage string) *[]string
- func (fs *FlagSet) StringListLong(long string, usage string) *[]string
- func (fs *FlagSet) StringListShort(short rune, usage string) *[]string
- func (fs *FlagSet) StringListVar(pointer *[]string, short rune, long string, usage string) Flag
- func (fs *FlagSet) StringLong(long string, def string, usage string) *string
- func (fs *FlagSet) StringSet(short rune, long string, usage string) *[]string
- func (fs *FlagSet) StringSetLong(long string, usage string) *[]string
- func (fs *FlagSet) StringSetShort(short rune, usage string) *[]string
- func (fs *FlagSet) StringSetVar(pointer *[]string, short rune, long string, usage string) Flag
- func (fs *FlagSet) StringShort(short rune, def string, usage string) *string
- func (fs *FlagSet) StringVar(pointer *string, short rune, long string, def string, usage string) Flag
- func (fs *FlagSet) Uint(short rune, long string, def uint, usage string) *uint
- func (fs *FlagSet) Uint64(short rune, long string, def uint64, usage string) *uint64
- func (fs *FlagSet) Uint64Config(cfg FlagConfig, def uint64) *uint64
- func (fs *FlagSet) Uint64Long(long string, def uint64, usage string) *uint64
- func (fs *FlagSet) Uint64Short(short rune, def uint64, usage string) *uint64
- func (fs *FlagSet) Uint64Var(pointer *uint64, short rune, long string, def uint64, usage string) Flag
- func (fs *FlagSet) UintConfig(cfg FlagConfig, def uint) *uint
- func (fs *FlagSet) UintLong(long string, def uint, usage string) *uint
- func (fs *FlagSet) UintShort(short rune, def uint, usage string) *uint
- func (fs *FlagSet) UintVar(pointer *uint, short rune, long string, def uint, usage string) Flag
- func (fs *FlagSet) Value(short rune, long string, value flag.Value, usage string) Flag
- func (fs *FlagSet) ValueLong(long string, value flag.Value, usage string) Flag
- func (fs *FlagSet) ValueShort(short rune, value flag.Value, usage string) Flag
- func (fs *FlagSet) WalkFlags(fn func(Flag) error) error
- type FlagSetAny
- type Flags
- type Option
- func WithConfigAllowMissingFile() Option
- func WithConfigFile(filename string) Option
- func WithConfigFileFlag(flagname string) Option
- func WithConfigFileParser(pf ConfigFileParseFunc) Option
- func WithConfigIgnoreUndefinedFlags() Option
- func WithEnvVarPrefix(prefix string) Option
- func WithEnvVarSplit(delimiter string) Option
- func WithEnvVars() Option
- func WithFilesystem(fs iofs.FS) Option
- type ParseContext
- type Resetter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrHelp should be returned by flag sets during parse, when the provided // args indicate the user has requested help. ErrHelp = flag.ErrHelp // ErrDuplicateFlag should be returned by flag sets when the user tries to // add a flag with the same name as a pre-existing flag. ErrDuplicateFlag = errors.New("duplicate flag") // ErrNotParsed may be returned by flag set methods which require the flag // set to have been successfully parsed, and that condition isn't satisfied. ErrNotParsed = errors.New("not parsed") // ErrAlreadyParsed may be returned by the parse method of flag sets, if the // flag set has already been successfully parsed, and cannot be parsed // again. ErrAlreadyParsed = errors.New("already parsed") // ErrUnknownFlag should be returned by flag sets methods to indicate that a // specific or user-requested flag was provided but could not be found. ErrUnknownFlag = errors.New("unknown flag") // ErrNoExec is returned when a command without an exec function is run. ErrNoExec = errors.New("no exec function") )
Functions ¶
func Parse ¶
func Parse(fs FlagSetAny, args []string, options ...Option) error
Parse the flag set with the provided args. Option values can be used to influence parse behavior. For example, options exist to read flags from environment variables, config files, etc.
Example (Args) ¶
fs := ff.NewFlagSet("myprogram") var ( listen = fs.StringLong("listen", "localhost:8080", "listen address") refresh = fs.Duration('r', "refresh", 15*time.Second, "refresh interval") debug = fs.Bool('d', "debug", "log debug information") ) err := ff.Parse(fs, []string{"--refresh=1s", "-d"}) fmt.Printf("err=%v\n", err) fmt.Printf("listen=%v\n", *listen) fmt.Printf("refresh=%v\n", *refresh) fmt.Printf("debug=%v\n", *debug)
Output: err=<nil> listen=localhost:8080 refresh=1s debug=true
Example (Config) ¶
fs := ff.NewFlagSet("myprogram") var ( listen = fs.StringLong("listen", "localhost:8080", "listen address") refresh = fs.Duration('r', "refresh", 15*time.Second, "refresh interval") debug = fs.Bool('d', "debug", "log debug information") _ = fs.String('c', "config", "", "path to config file") ) f, _ := os.CreateTemp("", "ExampleParse_config") defer func() { f.Close(); os.Remove(f.Name()) }() fmt.Fprint(f, ` debug listen localhost:9999 `) err := ff.Parse(fs, []string{"-c", f.Name()}, ff.WithConfigFileFlag("config"), ff.WithConfigFileParser(ff.PlainParser), ) fmt.Printf("err=%v\n", err) fmt.Printf("listen=%v\n", *listen) fmt.Printf("refresh=%v\n", *refresh) fmt.Printf("debug=%v\n", *debug)
Output: err=<nil> listen=localhost:9999 refresh=15s debug=true
Example (Env) ¶
fs := ff.NewFlagSet("myprogramenv") var ( listen = fs.StringLong("listen", "localhost:8080", "listen address") refresh = fs.Duration('r', "refresh", 15*time.Second, "refresh interval") debug = fs.Bool('d', "debug", "log debug information") ) defer os.Setenv("MY_PROGRAM_ENV_REFRESH", os.Getenv("MY_PROGRAM_ENV_REFRESH")) os.Setenv("MY_PROGRAM_ENV_REFRESH", "3s") err := ff.Parse(fs, []string{}, ff.WithEnvVarPrefix("MY_PROGRAM_ENV"), ) fmt.Printf("err=%v\n", err) fmt.Printf("listen=%v\n", *listen) fmt.Printf("refresh=%v\n", *refresh) fmt.Printf("debug=%v\n", *debug)
Output: err=<nil> listen=localhost:8080 refresh=3s debug=false
Example (Flag_set_features) ¶
fs := ff.NewFlagSet("myprogram") var ( addrs = fs.StringSet('a', "addr", "remote address (repeatable)") refresh = fs.DurationLong("refresh", 15*time.Second, "refresh interval") compress = fs.Bool('c', "compress", "enable compression") transform = fs.Bool('t', "transform", "enable transformation") loglevel = fs.StringEnum('l', "log", "log level: debug, info, error", "info", "debug", "error") _ = fs.StringLong("config", "", "config file (optional)") ) err := ff.Parse(fs, []string{"-afoo", "-a", "bar", "--log=debug", "-ct"}, ff.WithEnvVarPrefix("MY_PROGRAM"), ff.WithConfigFileFlag("config"), ff.WithConfigFileParser(ff.PlainParser), ) fmt.Printf("%s\n", ffhelp.Flags(fs)) fmt.Printf("err=%v\n", err) fmt.Printf("addrs=%v\n", *addrs) fmt.Printf("refresh=%v\n", *refresh) fmt.Printf("compress=%v\n", *compress) fmt.Printf("transform=%v\n", *transform) fmt.Printf("loglevel=%v\n", *loglevel)
Output: NAME myprogram FLAGS -a, --addr STRING remote address (repeatable) --refresh DURATION refresh interval (default: 15s) -c, --compress enable compression -t, --transform enable transformation -l, --log STRING log level: debug, info, error (default: info) --config STRING config file (optional) err=<nil> addrs=[foo bar] refresh=15s compress=true transform=true loglevel=debug
Example (Help) ¶
fs := ff.NewFlagSet("myprogram") var ( addrs = fs.StringSet('a', "addr", "remote address (repeatable)") compress = fs.Bool('c', "compress", "enable compression") transform = fs.Bool('t', "transform", "enable transformation") loglevel = fs.StringEnum('l', "log", "log level: debug, info, error", "info", "debug", "error") _ = fs.StringLong("config", "", "config file (optional)") ) err := ff.Parse(fs, []string{"-h"}, ff.WithEnvVarPrefix("MY_PROGRAM"), ff.WithConfigFileFlag("config"), ff.WithConfigFileParser(ff.PlainParser), ) if err != nil { fmt.Printf("%s\n", ffhelp.Flags(fs)) fmt.Printf("err=%v\n", err) } else { fmt.Printf("addrs=%v compress=%v transform=%v loglevel=%v\n", *addrs, *compress, *transform, *loglevel) }
Output: NAME myprogram FLAGS -a, --addr STRING remote address (repeatable) -c, --compress enable compression -t, --transform enable transformation -l, --log STRING log level: debug, info, error (default: info) --config STRING config file (optional) err=parse args: flag: help requested
Example (Parent) ¶
parentfs := ff.NewFlagSet("mycommand") var ( loglevel = parentfs.StringEnum('l', "log", "log level: debug, info, error", "info", "debug", "error") _ = parentfs.StringLong("config", "", "config file (optional)") ) childfs := ff.NewFlagSet("subcommand").SetParent(parentfs) var ( compress = childfs.Bool('c', "compress", "enable compression") transform = childfs.Bool('t', "transform", "enable transformation") refresh = childfs.DurationLong("refresh", 15*time.Second, "refresh interval") ) f, _ := os.CreateTemp("", "ExampleParse_parent") defer func() { f.Close(); os.Remove(f.Name()) }() fmt.Fprint(f, ` log error compress refresh 3s `) err := ff.Parse(childfs, []string{"--config", f.Name(), "--refresh=1s"}, ff.WithEnvVarPrefix("MY_PROGRAM"), ff.WithConfigFileFlag("config"), ff.WithConfigFileParser(ff.PlainParser), ) fmt.Printf("err=%v\n", err) fmt.Printf("loglevel=%v\n", *loglevel) fmt.Printf("compress=%v\n", *compress) fmt.Printf("transform=%v\n", *transform) fmt.Printf("refresh=%v\n", *refresh)
Output: err=<nil> loglevel=error compress=true transform=false refresh=1s
Example (Stdlib) ¶
fs := flag.NewFlagSet("myprogram", flag.ContinueOnError) var ( listen = fs.String("listen", "localhost:8080", "listen address") refresh = fs.Duration("refresh", 15*time.Second, "refresh interval") debug = fs.Bool("debug", false, "log debug information") ) err := ff.Parse(fs, []string{"--debug", "-refresh=2s", "-listen", "localhost:9999"}) fmt.Printf("err=%v\n", err) fmt.Printf("listen=%v\n", *listen) fmt.Printf("refresh=%v\n", *refresh) fmt.Printf("debug=%v\n", *debug)
Output: err=<nil> listen=localhost:9999 refresh=2s debug=true
func PlainParser ¶
PlainParser is a parser for config files in an extremely simple format. Each line is tokenized as a single key/value pair. The first space-delimited token in the line is interpreted as the flag name, and the rest of the line is interpreted as the flag value.
Any leading hyphens on the flag name are ignored. Lines with a flag name but no value are interpreted as booleans, and the value is set to true.
Flag values are trimmed of leading and trailing whitespace, but are otherwise unmodified. In particular, values are not quote-unescaped, and control characters like \n are not evaluated and instead passed through as literals.
Comments are supported via "#". End-of-line comments require a space between the end of the line and the "#" character.
An example config file follows.
# this is a full-line comment timeout 250ms # this is an end-of-line comment foo abc def # set foo to `abc def` foo 12345678 # repeated flags result in repeated calls to Set bar "abc def" # set bar to `"abc def"`, including quotes baz x\ny # set baz to `x\ny`, passing \n literally verbose # equivalent to `verbose true`
Types ¶
type Command ¶
type Command struct { // Name of the command, which is used when producing the help text for the // command, as well as for subcommand matching. // // Required. Name string // Usage is a single line string which should describe the syntax of the // command, including flags and arguments. It's typically printed at the top // of the help text for the command. For example, // // USAGE // cmd [FLAGS] subcmd [FLAGS] <ARG> [<ARG>...] // // Here, the usage string begins with "cmd [FLAGS] ...". // // Recommended. If not provided, the help text for the command should not // include a usage section. Usage string // ShortHelp is a single line which should very briefly describe the purpose // of the command in prose. It's typically printed next to the command name // when it appears as a subcommand in help text. For example, // // SUBCOMMANDS // commandname this is the short help string // // Recommended. ShortHelp string // LongHelp is a multi-line string, usually one or more paragraphs of prose, // which explain the command in detail. It's typically included in the help // output for the command, separate from other sections. // // Long help should be formatted for user readability. For example, if help // output is written to a terminal, long help should include newlines which // hard-wrap the string at an appropriate column width for that terminal. // // Optional. LongHelp string // Flags is the set of flags associated with, and parsed by, this command. // // When building a command tree, it's often useful to allow flags defined by // parent commands to be specified by any subcommand. A FlagSet supports // this behavior via SetParent, see the documentation of that method for // details. // // Optional. If not provided, an empty flag set will be constructed and used // so that the -h, --help flag works as expected. Flags Flags // Subcommands which are available underneath (i.e. after) this command. // Selecting a subcommand is done via a case-insensitive comparison of the // first post-parse argument to this command, against the name of each // subcommand. // // Optional. Subcommands []*Command // Exec is invoked by Run (or ParseAndRun) if this command was selected as // the terminal command during the parse phase. The args passed to Exec are // the args left over after parsing. // // Optional. If not provided, running this command will result in ErrNoExec. Exec func(ctx context.Context, args []string) error // contains filtered or unexported fields }
Command is a declarative structure that combines a main function with a flag set and zero or more subcommands. It's intended to model CLI applications which can be represented as a tree of such commands.
func (*Command) GetParent ¶
GetParent returns the parent command of this command, or nil if a parent hasn't been set. Parents are set during the parse phase, but only for commands which are traversed.
func (*Command) GetSelected ¶
GetSelected returns the terminal command selected during the parse phase, or nil if the command hasn't been successfully parsed.
func (*Command) Parse ¶
Parse the args and options against the defined command, which sets relevant flags, traverses the command hierarchy to select a terminal command, and captures the arguments that will be given to that command's exec function. The args should not include the program name: pass os.Args[1:], not os.Args.
func (*Command) ParseAndRun ¶
ParseAndRun calls Command.Parse and, upon success, Command.Run.
func (*Command) Reset ¶
Reset every command in the command tree to its initial state, including all flag sets. Every flag set must implement Resetter, or else reset will return an error.
func (*Command) Run ¶
Run the Exec function of the terminal command selected during the parse phase, passing the args left over after parsing. Calling Command.Run without first calling Command.Parse will result in ErrNotParsed.
type ConfigFileParseFunc ¶
ConfigFileParseFunc is a function that consumes the provided reader as a config file, and calls the provided set function for every name=value pair it discovers.
type Flag ¶
type Flag interface { // GetFlags should return the set of flags in which this flag is defined. // It's primarily used to produce help text for hierarchical commands. GetFlags() Flags // GetShortName should return the short name for this flag, if one is // defined. A short name is always a single valid rune (character) which is // typically parsed with a single leading hyphen, e.g. -f. GetShortName() (rune, bool) // GetLongName should return the long name for this flag, if one is defined. // A long name is always a non-empty string which is typically parsed with // two leading hyphens, e.g. --foo. GetLongName() (string, bool) // GetPlaceholder should return a string that can be used as a placeholder // for the flag value in help text. For example, a placeholder for a // string flag might be STRING. An empty placeholder is valid. GetPlaceholder() string // GetUsage should return a short description of the flag, which can be // included in the help text on the same line as the flag name(s). For // example, the usage string for a timeout flag used in an HTTP client might // be "timeout for outgoing HTTP requests". An empty usage string is valid, // but not recommended. GetUsage() string // GetDefault should return a string that represents the default value of // the flag in the context of help text. An empty string is valid, and // doesn't mean that the true default value of the flag is actually an empty // string. GetDefault() string // SetValue should parse the provided string into the appropriate type for // the flag, and set the flag to that parsed value. SetValue(string) error // GetValue should return the current value of the flag as a string. If no // value has been set, it should return the default value as a string. GetValue() string // IsSet should return true if SetValue has been called successfully. IsSet() bool }
Flag describes a single runtime configuration parameter, defined in a set of Flags, and with a value that can be parsed from a string.
Implementations are not expected to be safe for concurrent use.
type FlagConfig ¶
type FlagConfig struct { // ShortName is the short form name of the flag, which can be provided as a // commandline argument with a single dash - prefix. A rune value of 0 or // utf8.RuneError is considered an invalid short name and is ignored. // // At least one of ShortName and/or LongName is required. ShortName rune // LongName is the long form name of the flag, which can be provided as a // commandline argument with a double-dash -- prefix. Long names must be // non-empty, and cannot contain whitespace, control characters, single or // double quotes, backticks, or backslashes. // // At least one of ShortName and/or LongName is required. LongName string // Usage is a short help message for the flag, typically printed after the // flag name(s) on a single line in the help text. For example, a usage // string "set the foo parameter" might produce help text as follows. // // -f, --foo BAR set the foo parameter // // If the usage string contains a `backtick` quoted substring, that // substring will be treated as a placeholder, if a placeholder was not // otherwise explicitly provided. // // Recommended. Usage string // Value is used to parse and store the underlying value for the flag. // Package ffval provides helpers and definitions for common value types. // // Required. Value flag.Value // Placeholder represents an example value in the help text for the flag, // typically printed after the flag name(s). For example, a placeholder of // "BAR" might produce help text as follows. // // -f, --foo BAR set the foo parameter // // Optional. If not provided, a default based on the value type is used. Placeholder string // NoPlaceholder will force GetPlaceholder to return the empty string. This // can be useful for flags that don't need placeholders in their help text, // for example boolean flags. NoPlaceholder bool // NoDefault will force GetDefault to return the empty string. This can be // useful for flags whose default values don't need to be communicated in // help text. Note this does not affect the actual default value of the // flag. NoDefault bool }
FlagConfig collects the required config for a flag in a flag set.
type FlagSet ¶
type FlagSet struct {
// contains filtered or unexported fields
}
FlagSet is a standard implementation of Flags. It's broadly similar to a flag.FlagSet, but with additional capabilities inspired by getopt(3).
func NewFlagSet ¶
NewFlagSet returns a new flag set with the given name.
func NewFlagSetFrom ¶
NewFlagSetFrom is a helper method that calls NewFlagSet with name, and then FlagSet.AddStruct with val, which must be a pointer to a struct. Any error results in a panic.
As a special case, val may also be a pointer to a flag.FlagSet. In this case, the returned ff.FlagSet behaves differently than normal. It acts as a fixed "snapshot" of the flag.FlagSet, and so doesn't allow new flags to be added. To approximate the behavior of the standard library, every flag.FlagSet flag name is treated as a long name, and parsing treats single-hyphen and double-hyphen flag arguments identically: -abc is parsed as --abc rather than -a -b -c. The flag.FlagSet error handling strategy is (effectively) forced to ContinueOnError. The usage function is ignored, and usage is never printed as a side effect of parsing.
func (*FlagSet) AddFlag ¶
func (fs *FlagSet) AddFlag(cfg FlagConfig) (Flag, error)
AddFlag adds a flag to the flag set, as specified by the provided config. An error is returned if the config is invalid, or if a flag is already defined in the flag set with the same short or long name.
This is a fairly low level method. Consumers may prefer type-specific helpers like FlagSet.Bool, FlagSet.StringVar, etc.
func (*FlagSet) AddStruct ¶
AddStruct adds flags to the flag set from the given val, which must be a pointer to a struct. Each exported field in that struct with a valid `ff:` struct tag corresponds to a unique flag in the flag set. Those fields must be a supported ffval.ValueType or implement flag.Value.
The `ff:` struct tag is a sequence of comma- or pipe-delimited items. An item is either empty (and ignored), a key, or a key/value pair. Key/value pairs are expressed as either key=value (with =) or key:value (with :). Items, keys, and values are trimmed of whitespace before use. Values may be 'single quoted' and will be unquoted before use.
The following is a list of valid keys and their expected values. Any invalid item, key, or value in the `ff:` struct tag will result in an error.
- s, short, shortname -- value must be a single valid rune
- l, long, longname -- value must be a valid long name
- u, usage -- value must be a non-empty string
- d, def, default -- value must be a non-empty and assignable string
- p, placeholder -- value must be a non-empty string
- noplaceholder -- no value
- nodefault -- no value
See the example for more detail.
Example ¶
var firstFlags struct { Alpha string `ff:"shortname: a, longname: alpha, usage: alpha string, default: abc "` Beta int `ff:" longname: beta, usage: 'beta: an int', placeholder: β "` Delta bool `ff:"shortname: d, usage: 'delta, a bool', nodefault "` Epsilon bool `ff:"short: e, long: epsilon, usage: epsilon bool, nodefault "` } var secondFlags struct { Gamma string `ff:" short=g | long=gamma | | usage: gamma string "` Iota float64 `ff:" | long=iota | default=0.43 | usage: 🦊 "` Kappa ffval.StringSet `ff:" short=k | long=kappa | | usage: kappa (repeatable) "` } fs := ff.NewFlagSet("mycommand") fs.AddStruct(&firstFlags) fs.AddStruct(&secondFlags) fmt.Print(ffhelp.Flags(fs))
Output: NAME mycommand FLAGS -a, --alpha STRING alpha string (default: abc) --beta β beta: an int (default: 0) -d delta, a bool -e, --epsilon epsilon bool -g, --gamma STRING gamma string --iota FLOAT64 🦊 (default: 0.43) -k, --kappa STRING kappa (repeatable)
func (*FlagSet) Bool ¶
Bool defines a new default false bool flag in the flag set, and panics on any error.
func (*FlagSet) BoolConfig ¶
func (fs *FlagSet) BoolConfig(cfg FlagConfig) *bool
BoolConfig defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) BoolDefault ¶
BoolDefault defines a new bool flag in the flag set, and panics on any error. Bool flags should almost always be default false; prefer Bool to BoolDefault.
func (*FlagSet) BoolLong ¶
BoolLong defines a new default false bool flag in the flag set, and panics on any error.
func (*FlagSet) BoolLongDefault ¶
BoolLongDefault defines a new bool flag in the flag set, and panics on any error. Bool flags should almost always be default false; prefer BoolLong to BoolLongDefault.
func (*FlagSet) BoolShort ¶
BoolShort defines a new default false bool flag in the flag set, and panics on any error.
func (*FlagSet) BoolShortDefault ¶
BoolShortDefault defines a new bool flag in the flag set, and panics on any error. Bool flags should almost always be default false; prefer BoolShort to BoolShortDefault.
func (*FlagSet) BoolVar ¶
BoolVar defines a new default false bool flag in the flag set, and panics on any error.
func (*FlagSet) BoolVarDefault ¶
func (fs *FlagSet) BoolVarDefault(pointer *bool, short rune, long string, def bool, usage string) Flag
BoolVarDefault defines a new bool flag in the flag set, and panics on any error. Bool flags should almost always be default false; prefer BoolVar to BoolVarDefault.
func (*FlagSet) Duration ¶
func (fs *FlagSet) Duration(short rune, long string, def time.Duration, usage string) *time.Duration
Duration defines a new flag in the flag set, and panics on any error.
func (*FlagSet) DurationConfig ¶
DurationConfig defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) DurationLong ¶
DurationLong defines a new flag in the flag set, and panics on any error.
func (*FlagSet) DurationShort ¶
DurationShort defines a new flag in the flag set, and panics on any error.
func (*FlagSet) DurationVar ¶
func (fs *FlagSet) DurationVar(pointer *time.Duration, short rune, long string, def time.Duration, usage string) Flag
DurationVar defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Float64Config ¶
func (fs *FlagSet) Float64Config(cfg FlagConfig, def float64) *float64
Float64Config defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) Float64Long ¶
Float64Long defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Float64Short ¶
Float64Short defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Float64Var ¶
func (fs *FlagSet) Float64Var(pointer *float64, short rune, long string, def float64, usage string) Flag
Float64Var defines a new flag in the flag set, and panics on any error.
func (*FlagSet) GetFlag ¶
GetFlag returns the first flag known to the flag set that matches the given name. This includes all parent flags, if a parent has been set. The name is compared against each flag's long name, and, if the name is a single rune, it's also compared against each flag's short name.
func (*FlagSet) IntConfig ¶
func (fs *FlagSet) IntConfig(cfg FlagConfig, def int) *int
IntConfig defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) Parse ¶
Parse the provided args against the flag set, assigning flag values as appropriate. Args are matched to flags defined in this flag set, and, if a parent is set, all parent flag sets, recursively. If a specified flag can't be found, parse fails with ErrUnknownFlag. After a successful parse, subsequent calls to parse fail with ErrAlreadyParsed, until and unless the flag set is reset.
func (*FlagSet) Reset ¶
Reset the flag set, and all of the flags defined in the flag set, to their initial state. After a successful reset, the flag set may be parsed as if it were newly constructed.
func (*FlagSet) SetParent ¶
SetParent assigns a parent flag set to this one, making all parent flags available, recursively, to the receiver. For example, Parse will match against any parent flag, WalkFlags will traverse all parent flags, etc.
This method returns its receiver to allow for builder-style initialization.
func (*FlagSet) StringConfig ¶
func (fs *FlagSet) StringConfig(cfg FlagConfig, def string) *string
StringConfig defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) StringEnum ¶
StringEnum defines a new enum in the flag set, and panics on any error. The default is the first valid value. At least one valid value is required.
func (*FlagSet) StringEnumLong ¶
StringEnumLong defines a new enum in the flag set, and panics on any error. The default is the first valid value. At least one valid value is required.
func (*FlagSet) StringEnumShort ¶
StringEnumShort defines a new enum in the flag set, and panics on any error. The default is the first valid value. At least one valid value is required.
func (*FlagSet) StringEnumVar ¶
func (fs *FlagSet) StringEnumVar(pointer *string, short rune, long string, usage string, valid ...string) Flag
StringEnumVar defines a new enum in the flag set, and panics on any error. The default is the first valid value. At least one valid value is required.
func (*FlagSet) StringList ¶
StringList defines a new flag in the flag set, and panics on any error. See FlagSet.StringListVar for more details.
func (*FlagSet) StringListLong ¶
StringListLong defines a new flag in the flag set, and panics on any error. See FlagSet.StringListVar for more details.
func (*FlagSet) StringListShort ¶
StringListShort defines a new flag in the flag set, and panics on any error. See FlagSet.StringListVar for more details.
func (*FlagSet) StringListVar ¶
StringListVar defines a new flag in the flag set, and panics on any error.
The flag represents a list of strings, where each call to Set adds a new value to the list. Duplicate values are permitted.
func (*FlagSet) StringLong ¶
StringLong defines a new flag in the flag set, and panics on any error.
func (*FlagSet) StringSet ¶
StringSet defines a new flag in the flag set, and panics on any error. See FlagSet.StringSetVar for more details.
func (*FlagSet) StringSetLong ¶
StringSetLong defines a new flag in the flag set, and panics on any error. See FlagSet.StringSetVar for more details.
func (*FlagSet) StringSetShort ¶
StringSetShort defines a new flag in the flag set, and panics on any error. See FlagSet.StringSetVar for more details.
func (*FlagSet) StringSetVar ¶
StringSetVar defines a new flag in the flag set, and panics on any error.
The flag represents a unique list of strings, where each call to Set adds a new value to the list. Duplicate values are silently dropped.
func (*FlagSet) StringShort ¶
StringShort defines a new flag in the flag set, and panics on any error.
func (*FlagSet) StringVar ¶
func (fs *FlagSet) StringVar(pointer *string, short rune, long string, def string, usage string) Flag
StringVar defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Uint64Config ¶
func (fs *FlagSet) Uint64Config(cfg FlagConfig, def uint64) *uint64
Uint64Config defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) Uint64Long ¶
Uint64Long defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Uint64Short ¶
Uint64Short defines a new flag in the flag set, and panics on any error.
func (*FlagSet) Uint64Var ¶
func (fs *FlagSet) Uint64Var(pointer *uint64, short rune, long string, def uint64, usage string) Flag
Uint64Var defines a new flag in the flag set, and panics on any error.
func (*FlagSet) UintConfig ¶
func (fs *FlagSet) UintConfig(cfg FlagConfig, def uint) *uint
UintConfig defines a new flag in the flag set, and panics on any error. The value field of the provided config is overwritten.
func (*FlagSet) ValueShort ¶
ValueShort defines a new flag in the flag set, and panics on any error.
type FlagSetAny ¶
type FlagSetAny any
FlagSetAny must be either a Flags interface, or a concrete *flag.FlagSet. Any other value will produce a runtime error.
The intent is to make the signature of functions like Parse more intuitive.
type Flags ¶
type Flags interface { // GetName should return the name of the flag set. GetName() string // Parse should parse the provided args against the flag set, setting flags // as appropriate, and saving leftover args to be returned by GetArgs. The // provided args shouldn't include the program name: callers should pass // os.Args[1:], not os.Args. Parse(args []string) error // IsParsed should return true if the flag set was successfully parsed. IsParsed() bool // WalkFlags should call the given fn for each flag known to the flag set. // Note that this may include flags that are actually defined in different // "parent" flag sets. If fn returns an error, WalkFlags should immediately // return that error. WalkFlags(fn func(Flag) error) error // GetFlag should find and return the first flag known to the flag set with // the given name. The name should always be compared against valid flag // long names. If name is a single valid rune, it should also be compared // against valid flag short names. Note that this may return a flag that is // actually defined in a different "parent" flag set. GetFlag(name string) (Flag, bool) // GetArgs should return the args left over after a successful call to // parse. If parse has not yet been called successfully, it should return an // empty (or nil) slice. GetArgs() []string }
Flags describes a collection of flags, typically associated with a specific command (or sub-command) executed by an end user.
Any valid Flags can be provided to Parse, or used as the Flags field in a Command. This allows consumers to use their own flag set implementation(s) while still taking advantage of the primary features of the module.
Implementations are not expected to be safe for concurrent use.
type Option ¶
type Option func(*ParseContext)
Option controls some aspect of parsing behavior.
func WithConfigAllowMissingFile ¶
func WithConfigAllowMissingFile() Option
WithConfigAllowMissingFile tells Parse to ignore config files that are specified but don't exist.
By default, missing config files result in a parse error.
func WithConfigFile ¶
WithConfigFile tells Parse to read the provided filename as a config file. Requires WithConfigFileParser, and overrides WithConfigFileFlag.
Because config files should generally be user-specifiable, this option should rarely be used; prefer WithConfigFileFlag.
func WithConfigFileFlag ¶
WithConfigFileFlag tells Parse to treat the flag with the given name as a config file. The flag name must be defined in the flag set consumed by parse. Requires WithConfigFileParser, and is overridden by WithConfigFile.
To specify a default config file, provide it as the default value of the corresponding flag.
func WithConfigFileParser ¶
func WithConfigFileParser(pf ConfigFileParseFunc) Option
WithConfigFileParser tells Parse how to interpret a config file. This option must be explicitly provided in order to parse config files.
By default, no config file parser is defined, and config files are ignored.
func WithConfigIgnoreUndefinedFlags ¶
func WithConfigIgnoreUndefinedFlags() Option
WithConfigIgnoreUndefinedFlags tells Parse to ignore flags in config files which are not defined in the parsed flag set. This option only applies to flags in config files.
By default, undefined flags in config files result in a parse error.
func WithEnvVarPrefix ¶
WithEnvVarPrefix is like WithEnvVars, but only considers environment variables beginning with the given prefix followed by an underscore. That prefix (and underscore) are removed before matching the env var key to a flag name. For example, the env var prefix `MYPROG` would mean that the env var `MYPROG_FOO` matches a flag named `foo`.
By default, flags are not parsed from environment variables at all.
func WithEnvVarSplit ¶
WithEnvVarSplit tells Parse to split environment variable values on the given delimiter, and to set the flag multiple times, once for each delimited token. Values produced in this way are not trimmed of whitespace.
For example, the env var `FOO=a,b,c` would by default set a flag named `foo` one time, with the value `a,b,c`. Providing WithEnvVarSplit with a comma delimiter would set `foo` multiple times, with the values `a`, `b`, and `c`.
By default, no splitting of environment variable values occurs.
func WithEnvVars ¶
func WithEnvVars() Option
WithEnvVars tells Parse to set flags from environment variables. Flags are matched to environment variables by capitalizing the flag name, and replacing separator characters like periods or hyphens with underscores.
By default, flags are not parsed from environment variables at all.
type ParseContext ¶
type ParseContext struct {
// contains filtered or unexported fields
}
ParseContext receives and maintains parse options.
type Resetter ¶
type Resetter interface { // Reset should revert the flag set to its initial state, including all // flags defined in the flag set. If reset returns successfully, the flag // set should be as if it were newly constructed: IsParsed should return // false, GetArgs should return an empty slice, etc. Reset() error }
Resetter may optionally be implemented by Flags.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
examples
|
|
Package ffenv provides an .env config file parser.
|
Package ffenv provides an .env config file parser. |
Package ffhelp provides tools to produce help text for flags and commands.
|
Package ffhelp provides tools to produce help text for flags and commands. |
Package ffjson provides a JSON config file parser.
|
Package ffjson provides a JSON config file parser. |
Package fftest provides tools for testing flag sets.
|
Package fftest provides tools for testing flag sets. |
Package fftoml provides a TOML config file parser.
|
Package fftoml provides a TOML config file parser. |
Package ffval provides common flag value types and helpers.
|
Package ffval provides common flag value types and helpers. |
Package ffyaml provides a YAML config file parser.
|
Package ffyaml provides a YAML config file parser. |
internal
|
|
ffdata
Package ffdata provides data-related helpers for ff packages.
|
Package ffdata provides data-related helpers for ff packages. |