Options¶
Options are mapped struct fields that can be set from command-line flags, defaults, environment variables, INI configuration, or runtime code.
An option is not a command, group, or positional argument container. It is usually a scalar, slice, map, function, or custom value type.
Basic Options¶
type Options struct {
Verbose bool `short:"v" long:"verbose" description:"Show verbose output"`
Output string `short:"o" long:"output" value-name:"FILE"`
}
Boolean options do not require an argument.
Passing --verbose sets the field to true.
Non-boolean options require a value unless optional is set.
Values may be passed as --output=file, --output file, -ofile,
-o=file, or -o file depending on option style and platform rules.
Optional Arguments¶
optional lets a non-bool option appear without a value.
Use optional-value to define what value is assigned in that case.
Then --color stores auto, while --color=always stores always.
Optional values are convenient, but they can make command lines harder to read. Prefer required values unless the bare option has a clear meaning.
Repeated Values¶
Slices collect repeated option values.
-I a -I b stores []string{"a", "b"}.
Maps collect key/value pairs. The default key/value delimiter is :.
--label env:prod --label tier:api stores two map entries.
Use key-value-delimiter when another separator is clearer.
Repeatable options can require a value count.
Use required:"N" to require at least N values,
or required:"N-M" to require a bounded range.
type Options struct {
Include []string `short:"I" long:"include" required:"1-"`
Label map[string]string `long:"label" required:"2-4"`
}
Scalar options still use boolean required values such as true or yes.
Numeric required values on scalar options are rejected,
except 1 and 0 keep their normal boolean meaning.
Choices¶
Use choices when only a small closed set is valid.
Choices improve three things at once: parse validation, help output, and shell completion.
For dynamic sets, prefer a custom completer and application-level validation. A tag should not pretend that a runtime-dependent list is static.
Counters¶
A counter is an integer option that increments instead of replacing the value.
The following forms are equivalent for a signed integer counter:
Counter values must be non-negative.
Counter fields must be integer or unsigned integer types.
Use a slice of bools only when each occurrence needs to remain observable.
Use counter when only the final level matters.
Option Relations¶
Use xor for mutually exclusive options.
--json --yaml fails because both options belong to the same xor group.
Use and when options only make sense together.
--user root fails unless --pass is also set.
Passing neither is allowed unless one member is also required.
Relation groups are local to the command where options are defined. They are not global application-level locks.
Hidden and Immediate Options¶
hidden keeps an option usable but removes it from help, completion, and docs.
Use it for compatibility aliases and internal switches.
immediate marks an option that should stop normal validation and execution.
This is for help, version, completion, generated docs, and similar flows.
Do not use immediate for ordinary business logic.
It changes parser control flow and should stay rare.
Pointers¶
Pointers preserve the difference between omitted input and explicit zero values.
If --limit is omitted, Limit stays nil.
If --limit=0 is passed, Limit points to zero.
Use pointers sparingly. They add nil checks throughout application code. For most options, a default value is simpler.
Custom Values¶
Custom value types can implement package conversion interfaces,
or standard encoding interfaces such as encoding.TextUnmarshaler.
Use custom conversion when the CLI value has a domain-specific syntax. Use validators when the value is still a normal string or number, but needs a simple constraint.
Defaults and Required Checks¶
Defaults and environment values are applied before required checks. This means a required option can be satisfied without appearing on the command line if a configured default source provides it.
This is intentional. required means the application must receive a value,
not necessarily that the user must type the flag in every invocation.
Option Design Rules¶
Keep command-line option names stable. Breaking names breaks scripts.
Prefer long names for all public options. Short names are valuable for frequent interactive use, but they are a limited namespace.
Keep option tags close to the field. If a field needs many tags, consider whether the option is doing too much.