Documentation
¶
Overview ¶
Package flagparser implements a flexible command line parser.
NewParser configures GNU-style defaults: short options use `-`, long options use `--`, the options-arguments separator is `--`, and option permutation is enabled. You can override any of these defaults to parse non-GNU command lines.
To parse arguments, you need to:
Create a *Parser instance (typically using the NewParser factory).
Initialize its options (e.g., with *Parser.AddOptionWithArgumentNone or by appending *Option values to the *Parser instance.).
Optionally, adjust the separator, permutation, and prefixes to match the desired command-line convention.
Invoke *Parser.Parse passing it `os.Args[1:]`.
The *Parser.Parse method returns a slice of Value.
Options-Arguments Separator ¶
The *Parser can be configured to define a separator after which any command line token is treated as a positional argument, regardless of its prefix. The GNU getopt implementation and the Go standard library do this using the `--` separator. NewParser configures `--` as separator.
Permutation ¶
By default, the parser permutes options ahead of positional arguments, matching the GNU getopt behavior. You can disable permutation (see the [*Parser.DisablePermute] knob) to preserve the original order, which can be useful when a subcommand expects its own flags.
Option Types ¶
Each Option has its own OptionType, which is one of these values:
OptionTypeEarlyArgumentNone: options processed before the actual command-line parsing to detect flags (e.g., `--help`) that should always cause specific actions (e.g., printing the help message on the stdout), regardless of the correctness of the rest of the command line. These options cannot receive arguments since they are processed ahead of the parsing.
OptionTypeStandaloneArgumentNone: options that cannot be grouped and that require no arguments (e.g., `--verbose`).
OptionTypeStandaloneArgumentRequired: options that cannot be grouped and that require an argument. The argument can be provided in a subsequent token (e.g., `--file FILE`) or after the `=` byte (`--file=FILE`).
OptionTypeStandaloneArgumentOptional: options that cannot be grouped and take an optional argument. The argument must be provided after the `=` byte (e.g., `--deepscan=true`, `--deepscan=false`). Omitting the value (e.g., `--deepscan`) causes the default value to be used.
OptionTypeGroupableArgumentNone: single-letter options that can be grouped together (e.g., `-xz` as a shortcut for `-x -z`).
OptionTypeGroupableArgumentRequired: like the previous section but an argument must be specified, either as a subsequent token (e.g., `-xzf FILE`) or directly after the option (`-xzfFILE`) -- note that even though the latter may be confusing it is a GNU extension.
Option Prefixes ¶
Each Option can define its own parsing prefix. Generally, it is advisable to use uniform prefixes for all options. For example, following the GNU convention, one should use the `-` prefix for groupable options and the `--` prefix for standalone options. This is the behavior that you get if you use *Parser.AddOptionWithArgumentNone and similar functions to initialize a parser. However, you can also use non-GNU conventions, such as standalone options prefixed by `-`, thus emulating the Go flag package option parsing style. To this end, manually create the Option.
This package also supports using distinct prefixes for distinct options of the same type. For example, both `+short` and `--verbose` could be standalone options. The only restriction, enforced by the *Parser, is that you cannot use the same prefix for groupable and standalone options. That is, if `-` is used for groupable options it cannot be used for standalone options as well.
The early options are an exception to this rule, since they are not really parsed, rather just pattern matched against the argv provided by the programmer. Therefore, it is possible to have `-a` and `-b` as groupable options and `-h` for help, provided that you declare `-h` as an early option. In other words, the prefixes assigned to early options do not have an impact on the single-prefix restriction.
Parsed Values ¶
ValueOption: contains a parsed *Option.
ValuePositionalArgument: contains a positional argument.
ValueOptionsArgumentsSeparator: contains the separator between the options and the arguments (usually `--`).
Example ¶
Consider the following command line arguments:
-sv --output /dev/null -- https://example.com/
Assume you define these options:
Option{Name:s Prefix:- Type:OptionTypeGroupableArgumentNone}
Option{Name:v Prefix:- Type:OptionTypeGroupableArgumentNone}
Option{Name:output Prefix:-- Type:OptionTypeStandaloneArgumentRequired}
Assume you use `--` as the options-arguments separator.
Then, the parser will return:
ValueOption{Token:scanner.TokenOption{Prefix:-} Name:s}
ValueOption{Token:scanner.TokenOption{Prefix:-} Name:v}
ValueOption{Token:scanner.TokenOption{Prefix:--} Name:output Value:/dev/null}
ValueOptionsArgumentsSeparator{}
ValuePositionalArgument{Value:https://example.com/}
See the package examples for more examples.
Example (CurlParsingFailureTooFewPositionalArguments) ¶
Failing parsing of curl-like invocation with too few positionals.
package main
import (
"fmt"
"math"
"github.com/bassosimone/flagparser"
"github.com/bassosimone/runtimex"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse
//
// Note: we're not providing a URL.
argv := []string{
"curl",
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
}
// Parse the options; this is where min/max positionals are enforced.
values, err := parser.Parse(argv[1:])
runtimex.Assert(len(values) <= 0 && err != nil)
// Print the error value
fmt.Printf("%s\n", err.Error())
}
Output: too few positional arguments: expected at least 1, got 0
Example (CurlParsingFailureTooManyPositionalArguments) ¶
Failing parsing of curl-like invocation with too many positionals.
package main
import (
"fmt"
"github.com/bassosimone/flagparser"
"github.com/bassosimone/runtimex"
)
func main() {
// Define a parser accepting curl-like command line options.
//
// Note: the default is to expect zero positionals.
parser := flagparser.NewParser()
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse
argv := []string{
"curl",
"https://www.example.com/",
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
}
// Parse the options; this is where min/max positionals are enforced.
values, err := parser.Parse(argv[1:])
runtimex.Assert(len(values) <= 0 && err != nil)
// Print the error value
fmt.Printf("%s\n", err.Error())
}
Output: too many positional arguments: expected at most 0, got 1
Example (CurlParsingFailureWithInvalidOption) ¶
Failing parsing of curl-like invocation with an unknown option.
package main
import (
"fmt"
"math"
"github.com/bassosimone/flagparser"
"github.com/bassosimone/runtimex"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse
argv := []string{
"curl",
"https://www.example.com/",
"--nonexistent-option", // will cause failure
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
}
// Parse the options; this is where `--nonexistent-option` causes a failure
values, err := parser.Parse(argv[1:])
runtimex.Assert(len(values) <= 0 && err != nil)
// Print the error value
fmt.Printf("%s\n", err.Error())
}
Output: unknown option: --nonexistent-option
Example (CurlParsingSuccessLongWithEqual) ¶
Successful parsing of curl-like invocation with long options where a required argument is provided after an '=' sign.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse; the `--output` argument uses `=`.
argv := []string{
"curl",
"https://www.example.com/",
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
}
// Parse the options; the early option wins over other errors.
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--fail] [--silent] [--show-error] [--location] [--output index.html] [https://www.example.com/]
Example (CurlParsingSuccessLongWithOptionalValueNotPresent) ¶
Successful parsing of curl-like invocation with long options where the optional option argument is not provided.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddLongOptionWithArgumentOptional("fail", "true")
parser.AddOptionWithArgumentRequired('o', "output")
// Define the argument vector to parse; the `--fail` argument uses the default value.
argv := []string{
"curl",
"https://www.example.com/",
"--fail",
"--output=index.html",
}
// Parse the options; the `--fail` gets assigned a default value.
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--fail=true] [--output index.html] [https://www.example.com/]
Example (CurlParsingSuccessLongWithOptionalValuePresent) ¶
Successful parsing of curl-like invocation with long options where the optional option argument is provided after the `=` sign.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddLongOptionWithArgumentOptional("fail", "true")
parser.AddOptionWithArgumentRequired('o', "output")
// Define the argument vector to parse; the `--fail` argument uses an explicit value.
argv := []string{
"curl",
"https://www.example.com/",
"--fail=false",
"--output=index.html",
}
// Parse the options; the `--fail` gets assigned a default value.
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--fail=false] [--output index.html] [https://www.example.com/]
Example (CurlParsingSuccessLongWithSpace) ¶
Successful parsing of curl-like invocation with long options where a required argument is provided as a separate token.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse; the `--output` argument is separate.
argv := []string{
"curl",
"https://www.example.com/",
"--fail",
"--silent",
"--show-error",
"--location",
"--output",
"index.html",
}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--fail] [--silent] [--show-error] [--location] [--output index.html] [https://www.example.com/]
Example (CurlParsingSuccessShortWithNoSpace) ¶
Successful parsing of curl-like invocation with short options where a required argument is glued to the last short flag (GNU extension).
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse; the `-o` argument is glued to the flag.
argv := []string{"curl", "https://www.example.com/", "-fsSLoindex.html"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [-f] [-s] [-S] [-L] [-o index.html] [https://www.example.com/]
Example (CurlParsingSuccessShortWithSpace) ¶
Successful parsing of curl-like invocation with short options where a required argument is provided as a separate token.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse; the `-o` argument is a separate token.
argv := []string{"curl", "https://www.example.com/", "-fsSLo", "index.html"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [-f] [-s] [-S] [-L] [-o index.html] [https://www.example.com/]
Example (CurlParsingSuccessShortWithSpaceAndDashValue) ¶
Successful parsing of curl-like invocation with short options where a required argument value is the `-` separate token (commonly used to indicate that we want to use the standard output).
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse; the `-o` argument is a separate token.
argv := []string{"curl", "https://www.example.com/", "-fsSLo", "-"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: we have reordering by default so options are sorted before
// positional arguments (respecting their relative order)
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [-f] [-s] [-S] [-L] [-o -] [https://www.example.com/]
Example (CurlParsingSuccessWithEarlyHelpLong) ¶
Successful parsing of curl-like invocation with `--help` acting as an "early" option that short-circuits parsing regardless of other errors.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddEarlyOption('h', "help")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse
argv := []string{
"curl",
"https://www.example.com/",
"--nonexistent-option", // should cause failure
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
"--help", // but we have `--help` here
}
// Parse the options; the early option wins over the nonexistent option
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--help]
Example (CurlParsingSuccessWithEarlyHelpShort) ¶
Successful parsing of curl-like invocation with `-h` acting as an "early" option that short-circuits parsing regardless of other errors.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting curl-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(1, math.MaxInt)
parser.AddOptionWithArgumentNone('f', "fail")
parser.AddEarlyOption('h', "help")
parser.AddOptionWithArgumentNone('L', "location")
parser.AddOptionWithArgumentRequired('o', "output")
parser.AddOptionWithArgumentNone('S', "show-error")
parser.AddOptionWithArgumentNone('s', "silent")
// Define the argument vector to parse
argv := []string{
"curl",
"https://www.example.com/",
"--nonexistent-option", // should cause failure
"--fail",
"--silent",
"--show-error",
"--location",
"--output=index.html",
"-h", // but we have `-h` here
}
// Parse the options; the early option wins over the nonexistent option
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [-h]
Example (DigParsingSuccessWithMixedPrefixes) ¶
Successful parsing of dig-like invocation mixing GNU-style `-p` with `+short`.
package main
import (
"fmt"
"log"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser with mixed prefixes and a groupable required argument.
parser := &flagparser.Parser{
MinPositionalArguments: 1,
MaxPositionalArguments: 4,
Options: []*flagparser.Option{
{
Name: "p",
Prefix: "-",
Type: flagparser.OptionTypeGroupableArgumentRequired,
},
{
Name: "short",
Prefix: "+",
Type: flagparser.OptionTypeStandaloneArgumentNone,
},
{
DefaultValue: "1024",
Name: "bufsize",
Prefix: "+",
Type: flagparser.OptionTypeStandaloneArgumentOptional,
},
},
}
// Define the argument vector to parse; `+bufsize` uses the default value.
argv := []string{"dig", "@8.8.8.8", "-p53", "IN", "+short", "+bufsize", "A", "example.com"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [-p 53] [+short] [+bufsize=1024] [@8.8.8.8] [IN] [A] [example.com]
Example (GitSubmoduleForeachWithSeparatorWithReordering) ¶
Successful parsing of git-submodule-foreach-like invocation with the options-positionals separator and option permutation enabled.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting git-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(0, math.MaxInt)
parser.AddOptionWithArgumentNone('r', "recursive")
// Define the argument vector to parse
argv := []string{"git", "submodule", "foreach", "--recursive", "--", "git", "status", "-v"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note: reordering probably does not give us the desired output
// unless the `--recursive` flag could be applied to `git`.
//
// You typically do not parse a command with subcommands directly
// using this parser but this example is here to show what happens
// and build a mental model of how it works.
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [--recursive] [submodule] [foreach] [--] [git] [status] [-v]
Example (GitSubmoduleForeachWithSeparatorWithoutReordering) ¶
Successful parsing of git-submodule-foreach-like invocation with the options-positionals separator and option permutation disabled.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting git-like command line options.
parser := flagparser.NewParser()
parser.DisablePermute = true
parser.SetMinMaxPositionalArguments(0, math.MaxInt)
parser.AddOptionWithArgumentNone('r', "recursive")
// Define the argument vector to parse
argv := []string{"git", "submodule", "foreach", "--recursive", "--", "git", "status", "-v"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note how this case gives us the correct positional result.
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [submodule] [foreach] [--recursive] [--] [git] [status] [-v]
Example (GitSubmoduleForeachWithoutSeparatorWithReordering) ¶
Failing parsing of git-submodule-foreach-like invocation without an explicit separator in the args and with option permutation enabled.
package main
import (
"fmt"
"math"
"github.com/bassosimone/flagparser"
"github.com/bassosimone/runtimex"
)
func main() {
// Define a parser accepting git-like command line options.
parser := flagparser.NewParser()
parser.SetMinMaxPositionalArguments(0, math.MaxInt)
parser.AddOptionWithArgumentNone('r', "recursive")
// Define the argument vector to parse
argv := []string{"git", "submodule", "foreach", "--recursive", "git", "status", "-v"}
// Parse the options
//
// Note: reordering probably does not give us the desired output
// and specifically the `-v` is stolen from `git status` and causes
// a parsing error, which is definitely not what we want.
//
// You typically do not parse a command with subcommands directly
// using this parser but this example is here to show what happens
// and build a mental model of how it works.
values, err := parser.Parse(argv[1:])
runtimex.Assert(len(values) <= 0 && err != nil)
// Print the error value
fmt.Printf("%s\n", err.Error())
}
Output: unknown option: -v
Example (GitSubmoduleForeachWithoutSeparatorWithoutReordering) ¶
Successful parsing of git-submodule-foreach-like invocation without an explicit separator in the args and with option permutation disabled.
package main
import (
"fmt"
"log"
"math"
"github.com/bassosimone/flagparser"
)
func main() {
// Define a parser accepting git-like command line options.
parser := flagparser.NewParser()
parser.DisablePermute = true
parser.SetMinMaxPositionalArguments(0, math.MaxInt)
parser.AddOptionWithArgumentNone('r', "recursive")
// Define the argument vector to parse
argv := []string{"git", "submodule", "foreach", "--recursive", "git", "status", "-v"}
// Parse the options
values, err := parser.Parse(argv[1:])
if err != nil {
log.Fatal(err)
}
// Print the parsed values to stdout
//
// Note how this case gives us the correct positional result.
for _, value := range values {
fmt.Printf("%+v\n", value.Strings())
}
}
Output: [submodule] [foreach] [--recursive] [git] [status] [-v]
Index ¶
- Constants
- type ErrAmbiguousPrefix
- type ErrEmptyOptionName
- type ErrEmptyOptionPrefix
- type ErrMultipleOptionsWithSameName
- type ErrOptionRequiresArgument
- type ErrOptionRequiresNoArgument
- type ErrTooFewPositionalArguments
- type ErrTooLongGroupableOptionName
- type ErrTooManyPositionalArguments
- type ErrUnknownOption
- type Option
- type OptionType
- type Parser
- func (px *Parser) AddEarlyOption(shortName byte, longName string)
- func (px *Parser) AddLongOptionWithArgumentOptional(longName, defaultValue string)
- func (px *Parser) AddOption(options ...*Option)
- func (px *Parser) AddOptionWithArgumentNone(shortName byte, longName string)
- func (px *Parser) AddOptionWithArgumentRequired(shortName byte, longName string)
- func (px *Parser) Parse(args []string) ([]Value, error)
- func (px *Parser) SetMinMaxPositionalArguments(minArgs, maxArgs int)
- type Value
- type ValueOption
- type ValueOptionsArgumentsSeparator
- type ValuePositionalArgument
Examples ¶
- Package (CurlParsingFailureTooFewPositionalArguments)
- Package (CurlParsingFailureTooManyPositionalArguments)
- Package (CurlParsingFailureWithInvalidOption)
- Package (CurlParsingSuccessLongWithEqual)
- Package (CurlParsingSuccessLongWithOptionalValueNotPresent)
- Package (CurlParsingSuccessLongWithOptionalValuePresent)
- Package (CurlParsingSuccessLongWithSpace)
- Package (CurlParsingSuccessShortWithNoSpace)
- Package (CurlParsingSuccessShortWithSpace)
- Package (CurlParsingSuccessShortWithSpaceAndDashValue)
- Package (CurlParsingSuccessWithEarlyHelpLong)
- Package (CurlParsingSuccessWithEarlyHelpShort)
- Package (DigParsingSuccessWithMixedPrefixes)
- Package (GitSubmoduleForeachWithSeparatorWithReordering)
- Package (GitSubmoduleForeachWithSeparatorWithoutReordering)
- Package (GitSubmoduleForeachWithoutSeparatorWithReordering)
- Package (GitSubmoduleForeachWithoutSeparatorWithoutReordering)
Constants ¶
const ( // OptionTypeEarlyArgumentNone indicates an early option requiring no arguments. // // Typically used for `-h` and `--help`. OptionTypeEarlyArgumentNone = optionKindEarly | optionArgumentNone // OptionTypeStandaloneArgumentNone indicates a standalone option requiring no arguments. // // Typically used for `--verbose` or `--quiet`. OptionTypeStandaloneArgumentNone = optionKindStandalone | optionArgumentNone // OptionTypeStandaloneArgumentRequired indicates a standalone option requiring an argument. // // Typically used for stuff like `--output FILE` (or `--output=FILE`). OptionTypeStandaloneArgumentRequired = optionKindStandalone | optionArgumentRequired // OptionTypeStandaloneArgumentOptional indicates a standalone option with an optional argument. // // Typically used for stuff like `--http=1.1` (or `--http` to get the default). OptionTypeStandaloneArgumentOptional = optionKindStandalone | optionArgumentOptional // OptionTypeGroupableArgumentNone indicates a groupable option requiring no arguments. // // Typically used for options like `-v` (for verbose). // // These options can be grouped together like in `-xvzd DIR`. OptionTypeGroupableArgumentNone = optionKindGroupable | optionArgumentNone // OptionTypeGroupableArgumentRequired indicates groupable option requiring an argument. // // Typically used for options like `-d DIR` or `-dDIR` (to select a directory). // // These options can be grouped together like in `-xvzd DIR`. OptionTypeGroupableArgumentRequired = optionKindGroupable | optionArgumentRequired )
These constants define the allowed OptionType values.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ErrAmbiguousPrefix ¶
type ErrAmbiguousPrefix struct {
// Prefix is the prefix that is used for both standalone and groupable options.
Prefix string
}
ErrAmbiguousPrefix indicates that the options contain ambiguous prefixes that are used for both standalone and groupable options.
func (ErrAmbiguousPrefix) Error ¶
func (err ErrAmbiguousPrefix) Error() string
Error returns a string representation of this error.
type ErrEmptyOptionName ¶
type ErrEmptyOptionName struct {
// Option is the option with the empty name.
Option *Option
}
ErrEmptyOptionName indicates that an option name is empty.
func (ErrEmptyOptionName) Error ¶
func (err ErrEmptyOptionName) Error() string
Error returns a string representation of this error.
type ErrEmptyOptionPrefix ¶
type ErrEmptyOptionPrefix struct {
// Option is the option with the empty prefix.
Option *Option
}
ErrEmptyOptionPrefix indicates that an option prefix is empty.
func (ErrEmptyOptionPrefix) Error ¶
func (err ErrEmptyOptionPrefix) Error() string
Error returns a string representation of this error.
type ErrMultipleOptionsWithSameName ¶
type ErrMultipleOptionsWithSameName struct {
// Name is the name of the option that appears multiple times.
Name string
// Options is a slice of options with the same name.
Options []*Option
}
ErrMultipleOptionWithSameName indicates that there are multiple options with the same name.
func (ErrMultipleOptionsWithSameName) Error ¶
func (err ErrMultipleOptionsWithSameName) Error() string
Error returns a string representation of this error.
type ErrOptionRequiresArgument ¶
type ErrOptionRequiresArgument struct {
// Option is the offending option
Option *Option
// Token is the related token
Token flagscanner.Token
}
ErrOptionRequiresArgument indicates that no argument was passed to an option that requires an argument.
func (ErrOptionRequiresArgument) Error ¶
func (err ErrOptionRequiresArgument) Error() string
Error returns a string representation of this error.
type ErrOptionRequiresNoArgument ¶
type ErrOptionRequiresNoArgument struct {
// Option is the offending option
Option *Option
// Token is the related token
Token flagscanner.Token
}
ErrOptionRequiresNoArgument indicates that an argument was passed to an option that requires no arguments.
func (ErrOptionRequiresNoArgument) Error ¶
func (err ErrOptionRequiresNoArgument) Error() string
Error returns a string representation of this error.
type ErrTooFewPositionalArguments ¶
type ErrTooFewPositionalArguments struct {
// Min is the minimum number of positional arguments required.
Min int
// Have is the number of positional arguments provided.
Have int
}
ErrTooFewPositionalArguments is returned when the number of positional arguments is less than the configured minimum.
func (ErrTooFewPositionalArguments) Error ¶
func (err ErrTooFewPositionalArguments) Error() string
Error returns a string representation of this error.
type ErrTooLongGroupableOptionName ¶
type ErrTooLongGroupableOptionName struct {
Option *Option
}
ErrTooLongGroupableOptionName indicates that a groupable option name is longer than one byte.
func (ErrTooLongGroupableOptionName) Error ¶
func (err ErrTooLongGroupableOptionName) Error() string
Error returns a string representation of this error.
type ErrTooManyPositionalArguments ¶
type ErrTooManyPositionalArguments struct {
// Max is the maximum number of positional arguments allowed.
Max int
// Have is the number of positional arguments provided.
Have int
}
ErrTooManyPositionalArguments is returned when the number of positional arguments is greater than the configured maximum.
func (ErrTooManyPositionalArguments) Error ¶
func (err ErrTooManyPositionalArguments) Error() string
Error returns a string representation of this error.
type ErrUnknownOption ¶
type ErrUnknownOption struct {
// Name is the name of the unknown option.
Name string
// Prefix is the prefix of the unknown option.
Prefix string
// Token is the token of the unknown option.
Token flagscanner.Token
}
ErrUnknownOption indicates that an option is unknown.
func (ErrUnknownOption) Error ¶
func (err ErrUnknownOption) Error() string
Error returns a string representation of this error.
type Option ¶
type Option struct {
// DefaultValue is the default value assigned to the option
// [Value] when the option argument is optional.
DefaultValue string
// Prefix is the prefix to use for parsing this option (e.g., `-`)
Prefix string
// Name is the option name without the prefix (e.g., `f`).
Name string
// Type is the option type.
Type OptionType
}
Option specifies the kind of option to parse.
func NewEarlyOption ¶
NewEarlyOption creates early options with no arguments using GNU prefixes (- for short, -- for long).
You typically use "early" options to register `-h` and `--help` such that when the user uses those flags, regardless of whether the command line is correct, they see the help text in the output rather than parsing errors.
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method returns a nil slice.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
func NewLongOptionWithArgumentOptional ¶
NewLongOptionWithArgumentOptional creates a long option with an optional argument and a default value using the GNU `--` prefix.
If the long option name is empty, this method returns a nil slice.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
func NewOptionWithArgumentNone ¶
NewOptionWithArgumentNone creates options with no arguments using GNU prefixes (- for short, -- for long).
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method returns a nil slice.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
func NewOptionWithArgumentRequired ¶
NewOptionWithArgumentRequired creates options with a required argument using GNU prefixes (- for short, -- for long).
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method returns a nil slice.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
type Parser ¶
type Parser struct {
// DisablePermute optionally disables permuting options and arguments.
//
// Consider the following command line arguments:
//
// https://www.google.com/ -H 'Host: google.com'
//
// The default behavior is to permute this to:
//
// -H 'Host: google.com' https://www.google.com/
//
// However, when DisablePermute is true, we keep the command
// line unmodified. While permuting is a nice-to-have property
// in general, consider instead the following case:
//
// foreach -kx git status -v
//
// With permutation, this command line would become:
//
// -kx -v foreach git status
//
// This is not the desired behavior if the foreach subcommand
// takes another command and its options as arguments.
//
// To make the above command line work with permutation, a
// user would instead need to write this:
//
// foreach -kx -- git status -v
//
// By setting DisablePermute to true, the `--` separator
// becomes unnecessary and the UX is improved.
DisablePermute bool
// MaxPositionalArguments is the maximum number of positional
// arguments allowed by the parser. The default is zero, meaning
// that the parser won't accept more than zero positionals.
MaxPositionalArguments int
// MinPositionalArguments is the minimum number of positional
// arguments allowed by the parser. The default is zero, meaning
// that the parser won't accept less than zero positionals.
MinPositionalArguments int
// OptionsArgumentsSeparator is the optional separator that terminates
// the parsing of options, treating all remaining tokens in the command
// line as positional arguments. The default is empty, meaning that
// the parser will always parse all the available options.
OptionsArgumentsSeparator string
// Options contains the optional options configured for this parser.
//
// When parsing, we will ensure there are no duplicate option names or
// ambiguous separators across all options.
//
// If you don't set this field, the parser will automatically
// configure itself to parse GNU-style options, meaning that it
// will use `-` as the prefix for short options and `--` as
// the prefix for long options. No options will be defined so
// any option will be considered unknown and cause a parse error.
Options []*Option
}
Parser is a command line parser.
Construct with NewParser to get GNU parsing semantics. Otherwise, if you need a distinct parser semantics, please construct manually.
func NewParser ¶
func NewParser() *Parser
NewParser creates a new *Parser following the GNU convention.
Specifically, we use these settings:
command line permutation is enabled
zero positional arguments are allowed
the separator is set to `--`
no options have been defined yet
Create *Parser manually when you need different defaults.
func (*Parser) AddEarlyOption ¶
AddEarlyOption adds an "early" short and long option taking no argument and using the `-` and `--` prefixes, which follow the GNU conventions.
You typically use "early" options to register `-h` and `--help` such that when the user uses those flags, regardless of whether the command line is correct, they see the help text in the output rather than parsing errors.
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method is a no-operation that does not change the *Parser.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
Use NewEarlyOption to construct options without mutating the parser.
func (*Parser) AddLongOptionWithArgumentOptional ¶
AddLongOptionWithArgumentOptional adds a long option with an optional argument with the given default value and using `--` prefix, which follows the GNU conventions.
If the long option name is empty, this method is a no-operation that does not change the *Parser.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
Use NewLongOptionWithArgumentOptional to construct options without mutating the parser.
func (*Parser) AddOption ¶
AddOption adds one or more options to the parser.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
func (*Parser) AddOptionWithArgumentNone ¶
AddOptionWithArgumentNone adds a short and long option taking no argument and using the `-` and `--` prefixes, which follow the GNU conventions.
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method is a no-operation that does not change the *Parser.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
Use NewOptionWithArgumentNone to construct options without mutating the parser.
func (*Parser) AddOptionWithArgumentRequired ¶
AddOptionWithArgumentRequired adds a short and long option with a required argument and using the `-` and `--` prefixes, which follow the GNU conventions.
A zero short option value skips adding the short option. An empty long option value skips adding the long option. If both are zero/empty, this method is a no-operation that does not change the *Parser.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid option names (e.g., a duplicate option name) will cause no errors until you attempt to parse the command line.
Use NewOptionWithArgumentRequired to construct options without mutating the parser.
func (*Parser) Parse ¶
Parse parses the command line arguments.
This method does not mutate *Parser and is safe to call concurrently.
The args MUST NOT include the program name.
func (*Parser) SetMinMaxPositionalArguments ¶
SetMinMaxPositionalArguments sets the minimum and maximum positional arguments.
This method MUTATES *Parser and is NOT SAFE to call concurrently.
Setting invalid minimum and maximum positional arguments values will cause no errors until you attempt to parse the command line.
type Value ¶
type Value interface {
// Strings returns the strings to append to a slice
// to reconstruct the original command line.
Strings() []string
// Token returns the scanner token.
Token() flagscanner.Token
}
Value is a value parsed by the *Parser.
type ValueOption ¶
type ValueOption struct {
// Option is the corresponding [*Option].
Option *Option
// Tok is the token from which we parsed this [*Option].
Tok flagscanner.Token
// Value is the possibly-empty value. Specifically:
//
// 1. For [OptionTypeEarlyArgumentNone] this field is empty.
//
// 2. For [OptionTypeStandaloneArgumentNone] this field is empty.
//
// 3. For [OptionTypeGroupedArgumentNone] this field is empty.
//
// 4. For [OptionTypeStandaloneArgumentRequired] this field
// contains the value of the parsed argument.
//
// 5. For [OptionTypeGroupedArgumentRequired] this field
// contains the value of the parsed argument.
//
// 6. For [OptionTypeStandaloneArgumentOptional] this field
// contains the value of the parsed argument, if any,
// or the default value specified in [*Option], otherwise.
Value string
}
type ValueOptionsArgumentsSeparator ¶
type ValueOptionsArgumentsSeparator struct {
// Separator is the separator value.
Separator string
// Tok is the token associated with the item.
Tok flagscanner.Token
}
ValueOptionsArgumentsSeparator is a Value containing a parsed separator.
func (ValueOptionsArgumentsSeparator) Strings ¶
func (s ValueOptionsArgumentsSeparator) Strings() []string
Strings implements Value.
func (ValueOptionsArgumentsSeparator) Token ¶
func (val ValueOptionsArgumentsSeparator) Token() flagscanner.Token
Token implements Value.
type ValuePositionalArgument ¶
type ValuePositionalArgument struct {
// Tok is the token associated with the value.
Tok flagscanner.Token
// Value is the argument value.
Value string
}
ValuePositionalArgument is a Value containing a parsed positional argument.
func (ValuePositionalArgument) Strings ¶
func (a ValuePositionalArgument) Strings() []string
Strings implements Value.
func (ValuePositionalArgument) Token ¶
func (val ValuePositionalArgument) Token() flagscanner.Token
Token implements Value.