Documentation
¶
Overview ¶
Package optargs provides a collection of CLI parsing utilities in order to aid in the development of command line applications.
POSIX/GNU GetOpt ¶
At the heart of the optargs package is a Go implementation of the GNU glibc versions the getopt(3), getopt_long(3), and getopt_long_only(3) functions.
Leveraging GNU/POSIX conventions as the backend parser option means that the parser has a very large degree of flexibility without restricting application design choices.
For example, POSIX/GNU allows for the following:
- short-only options.
- long-only options.
- long and short options that do not require a value. I.e. it should be possoble to pass `--foo` and specify that it never takes a value, and any attempt to pass it a value should be ignored or or result in an error.
- short-options of any character that is a valid `isgraph()` character; with the exception of `-`, `:` and `;`. This means that the following options are valid: -=, -+, -{, -}, -^, -!, -@, etc.
- short-option compaction: `-abc` is the equivalent of `-a -b -c`
- short-option compaction with optional args: `-abarg` is the equivalent of `-a -b arg`
- arguments to short options that begin with `-`: `-a -1` should pass `-1` as an argument to `-a`
- long-arguments that include any `isgraph()` character in the name, this includes allowing `=` in the name of the argument. For example, `--foo=bar=boo` should map `foo=bar` as the Flag, and `boo` as the value to the flag. This potentially also allows for curious long-arg syntax sych as: `--command:arg=value`.
- many-to-one flag mappings. For example, the GNU `ls` command supports `--format=<format>` where each possible `<format>` options is also supported by a unique short-option. For example: `--format=across` = `-x`, `--format=commas` = `-m`, `--format=horizontal` = `-x`, `--format=long` = `-l`, etc.
- The GNU `-W` flag which allows short-options to behave like an undefined long-option. E.g. `-W foo` should be interpretted as if `--foo` was passed to the application.
- long-options that may look similar, but behave differently, from short options. E.g. `-c` and `--c` are allowed to behave differently.
It is always possible to implement a Flag handler which imposes opinionated rules atop a non-opinionated parser, but it is not possible to write a less opinionated Flag handler atop an opinionated parser. To that end, the [optarg] parsers do not make any judgements outside of strictly adhering to the POSIX/GNU conventions. Applications are free to implement their own argument handler to best-fit their application's needs.
Flags() ¶
Optargs supports traditional Go style flags which act as convenience methods around GetOpt, GetOptLong, and GetOptLongOnly with the aim of fully supporting drop-in replacements commonly used CLI tooling, such as:
While these packages are quite useful, they have some fundamental limitations and quirks that come from their design choices which aim to be overcome by optargs and in the case of spf13/pflag, those quirks ultimately percolate up to the user, such as spf13/pflag's boolean flags. Or putting arbitrary restrictions on applications, such as suporting long-only options, but not allowing short-only options. Or not supporting true non-option flags. I.e. many (all?) of the existing Go flag packages only allow an argument to a flag to be optional or required and are not capable of handling flags that never require an argument.
Index ¶
- type ArgType
- type CommandRegistry
- func (cr CommandRegistry) AddAlias(alias, existingCommand string) error
- func (cr CommandRegistry) AddCmd(name string, parser *Parser) *Parser
- func (cr CommandRegistry) ExecuteCommand(name string, args []string) (*Parser, error)
- func (cr CommandRegistry) ExecuteCommandCaseInsensitive(name string, args []string, caseIgnore bool) (*Parser, error)
- func (cr CommandRegistry) GetAliases(targetParser *Parser) []string
- func (cr CommandRegistry) GetCommand(name string) (*Parser, bool)
- func (cr CommandRegistry) GetCommandCaseInsensitive(name string, caseIgnore bool) (*Parser, bool)
- func (cr CommandRegistry) HasCommands() bool
- func (cr CommandRegistry) ListCommands() map[string]*Parser
- type Flag
- type Option
- type ParseMode
- type Parser
- func GetOpt(args []string, optstring string) (*Parser, error)
- func GetOptLong(args []string, optstring string, longopts []Flag) (*Parser, error)
- func GetOptLongOnly(args []string, optstring string, longopts []Flag) (*Parser, error)
- func NewParser(config ParserConfig, shortOpts map[byte]*Flag, longOpts map[string]*Flag, ...) (*Parser, error)
- func NewParserWithCaseInsensitiveCommands(shortOpts map[byte]*Flag, longOpts map[string]*Flag, args []string, ...) (*Parser, error)
- func (p *Parser) AddAlias(alias, existingCommand string) error
- func (p *Parser) AddCmd(name string, parser *Parser) *Parser
- func (p *Parser) ExecuteCommand(name string, args []string) (*Parser, error)
- func (p *Parser) GetAliases(targetParser *Parser) []string
- func (p *Parser) GetCommand(name string) (*Parser, bool)
- func (p *Parser) HasCommands() bool
- func (p *Parser) ListCommands() map[string]*Parser
- func (p *Parser) Options() iter.Seq2[Option, error]
- type ParserConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CommandRegistry ¶
CommandRegistry manages subcommands for a parser using a simple map
func NewCommandRegistry ¶
func NewCommandRegistry() CommandRegistry
NewCommandRegistry creates a new command registry
func (CommandRegistry) AddAlias ¶
func (cr CommandRegistry) AddAlias(alias, existingCommand string) error
AddAlias creates an alias for an existing command
func (CommandRegistry) AddCmd ¶
func (cr CommandRegistry) AddCmd(name string, parser *Parser) *Parser
AddCmd registers a new subcommand with the parser Returns the registered parser for chaining
func (CommandRegistry) ExecuteCommand ¶
func (cr CommandRegistry) ExecuteCommand(name string, args []string) (*Parser, error)
ExecuteCommand finds and executes a command
func (CommandRegistry) ExecuteCommandCaseInsensitive ¶
func (cr CommandRegistry) ExecuteCommandCaseInsensitive(name string, args []string, caseIgnore bool) (*Parser, error)
ExecuteCommandCaseInsensitive finds and executes a command with case insensitive matching
func (CommandRegistry) GetAliases ¶
func (cr CommandRegistry) GetAliases(targetParser *Parser) []string
GetAliases returns all aliases for a given parser
func (CommandRegistry) GetCommand ¶
func (cr CommandRegistry) GetCommand(name string) (*Parser, bool)
GetCommand retrieves a parser by command name
func (CommandRegistry) GetCommandCaseInsensitive ¶
func (cr CommandRegistry) GetCommandCaseInsensitive(name string, caseIgnore bool) (*Parser, bool)
GetCommandCaseInsensitive retrieves a parser by command name with case insensitive matching
func (CommandRegistry) HasCommands ¶
func (cr CommandRegistry) HasCommands() bool
HasCommands returns true if any commands are registered
func (CommandRegistry) ListCommands ¶
func (cr CommandRegistry) ListCommands() map[string]*Parser
ListCommands returns all command mappings
type Parser ¶
type Parser struct {
Args []string
// Command support - simple map of command name to parser
Commands CommandRegistry
// contains filtered or unexported fields
}
func GetOptLong ¶
func GetOptLongOnly ¶
func NewParserWithCaseInsensitiveCommands ¶
func NewParserWithCaseInsensitiveCommands(shortOpts map[byte]*Flag, longOpts map[string]*Flag, args []string, parent *Parser) (*Parser, error)
NewParserWithCaseInsensitiveCommands creates a new parser with case insensitive command matching enabled
func (*Parser) ExecuteCommand ¶
ExecuteCommand finds and executes a command
func (*Parser) GetAliases ¶
GetAliases returns all aliases for a given parser
func (*Parser) GetCommand ¶
GetCommand retrieves a parser by command name
func (*Parser) HasCommands ¶
HasCommands returns true if any commands are registered
func (*Parser) ListCommands ¶
ListCommands returns all command mappings
type ParserConfig ¶
type ParserConfig struct {
// contains filtered or unexported fields
}