Documentation
¶
Overview ¶
Input Sources and Precedence ¶
This library will always parse a program's command line arguments for Inputs. However, inputs can additionally be parsed from environment variables or default values, in that order of precedence. For example, if an input can be parsed from all of those places (command line argument, environment variable, and default value), all will be parsed, but the value from the command line will take precedence over the value from the environment variable, and the value from the environment variable will take precedence over the default value.
Command Line Syntax ¶
Command line arguments are classified as one of the following:
- Options: arguments that begin with "-" or "--" and may or may not require a value.
- Positional Arguments: arguments that are identified by the order in which they appear among other positional arguments.
- Subcommands: All arguments that follow belong to this command.
Command line arguments are parsed as options until a positional argument, subcommand, or an argument of just "--" is encountered. In other words, any options that belong to a command must come before any of that command's positional arguments or subcommands.
Positional arguments and subcommands are mutually exclusive since allowing both to exist at once would invite unnecessary ambiguity when parsing because there's no reliable way to tell if an argument would be a positional argument or the name of a subcommand. Furthermore, positional arguments that are required must appear before any optional ones since it would be impossible to tell when parsing whether a positional argument is filling the spot of a required one or an optional one. Therefore, the format of a command is structured like this:
command [options] [<required_pos_args> [optional_pos_args] [any_surplus_post_args...] | subcommand ...]
Options ¶
There are only two types of options in terms of syntax:
- boolean: Rather than providing some value, the mere presence of this type of option means something. For example, the "--all" in "ls --all" does not take a value; it just modifies the list command to list "all" files.
- non-boolean: This type of option requires a value. For example, in "ls --hide go.sum", the option "--hide" requires a file name or pattern.
Non-boolean options must have a value attached. In other words, while options themselves can either be required or optional, there is no such thing as an option that may or may not have a value.
Options can have appear in one of two forms and can have a name for each form: long or short. Typically an option's long name is more than one character, but an option's short name can only be a single character. Long form options are provided by prefixing the option's name with two hyphens ("--"), and they must appear one at a time, separately. Short form options are provided by prefixing the options short name with a single hyphen ("-"), and they can be "stacked", meaning under certain conditions, they can appear one after the other in the same command line argument.
The following are some common ways of how options can be provided:
--opt // long form boolean option "opt" -o // short form boolean option "o" --opt=val // long form non-boolean option with value of "val" --opt val // same as above, non-boolean options can provide their value as the next command line argument -a -b // two short form boolean options, "a" and "b" -ab // either same as above, or short form non-boolean option "a" with value of "b" (depends on specified command structure)
Basic Usage ¶
c := cli.New(). Help("A full example program"). Opt(cli.NewBoolOpt("yes"). Short('y'). Help("A boolean option on the root command."). Env("YES")). Opt(cli.NewOpt("str"). Short('s'). Help("A string option on the root command."). Env("STR")). Subcmd(cli.NewCmd("nodat"). Help("Subcommand with no data")). Subcmd(cli.NewCmd("floats"). Help("Print values for each supported float type (both options required)."). Opt(cli.NewFloat32Opt("f32").Help("32 bit float").Required()). Opt(cli.NewFloat64Opt("f64").Help("64 bit float").Required())). Subcmd(cli.NewCmd("ints"). Help("Print values for each supported signed integer type."). Opt(cli.NewIntOpt("int").Help("Print the given int value."))). ParseOrExit()
Index ¶
- Variables
- func DefaultFullHelp(c *CommandInfo) string
- func DefaultHelpGenerator(src Input, c *CommandInfo) string
- func DefaultShortHelp(c *CommandInfo) string
- func Fatal(code int, v any)
- func Get[T any](c *Command, id string) T
- func GetAll[T any](c *Command, id string) []T
- func GetAllSeq[T any](c *Command, id string) iter.Seq[T]
- func GetOr[T any](c *Command, id string, fallback T) T
- func GetOrFunc[T any](c *Command, id string, fn func() T) T
- func Lookup[T any](c *Command, id string) (T, bool)
- func ParseBool(s string) (any, error)
- func ParseDuration(s string) (any, error)
- func ParseFloat32(s string) (any, error)
- func ParseFloat64(s string) (any, error)
- func ParseInt(s string) (any, error)
- func ParseURL(s string) (any, error)
- func ParseUint(s string) (any, error)
- type Command
- type CommandInfo
- func (c CommandInfo) Arg(pa InputInfo) CommandInfo
- func (c CommandInfo) ExtraHelp(extra string) CommandInfo
- func (c CommandInfo) Help(blurb string) CommandInfo
- func (c CommandInfo) Opt(o InputInfo) CommandInfo
- func (in *CommandInfo) Parse() (*Command, error)
- func (in CommandInfo) ParseOrExit() *Command
- func (in *CommandInfo) ParseThese(args ...string) (*Command, error)
- func (in CommandInfo) ParseTheseOrExit(args ...string) *Command
- func (c CommandInfo) Subcmd(sc CommandInfo) CommandInfo
- func (c CommandInfo) Usage(lines ...string) CommandInfo
- type HelpGenerator
- type HelpOrVersionRequested
- type Input
- type InputInfo
- func NewArg(id string) InputInfo
- func NewBoolOpt(id string) InputInfo
- func NewFloat32Opt(id string) InputInfo
- func NewFloat64Opt(id string) InputInfo
- func NewIntOpt(id string) InputInfo
- func NewOpt(id string) InputInfo
- func NewUintOpt(id string) InputInfo
- func NewVersionOpt(short byte, long string, cfg VersionOptConfig) InputInfo
- func (in InputInfo) Default(v string) InputInfo
- func (in InputInfo) Env(e string) InputInfo
- func (in InputInfo) Help(blurb string) InputInfo
- func (in InputInfo) Long(name string) InputInfo
- func (in InputInfo) Required() InputInfo
- func (in InputInfo) Short(c byte) InputInfo
- func (in InputInfo) ShortOnly(c byte) InputInfo
- func (in InputInfo) WithHelpGen(hg HelpGenerator) InputInfo
- func (in InputInfo) WithParser(vp ValueParser) InputInfo
- func (in InputInfo) WithValueName(name string) InputInfo
- func (in InputInfo) WithVersioner(ver Versioner) InputInfo
- type MissingArgsError
- type MissingOptionValueError
- type MissingOptionsError
- type ParsedFrom
- type UnknownOptionError
- type UnknownSubcmdError
- type ValueParser
- type VersionOptConfig
- type Versioner
Examples ¶
- CommandInfo.Arg
- CommandInfo.ExtraHelp
- CommandInfo.Opt
- CommandInfo.Usage
- DefaultFullHelp
- DefaultShortHelp (Complex)
- DefaultShortHelp (Simple)
- DefaultShortHelp (SimpleWithSubcommands)
- Get (Option)
- Get (PositionalArgs)
- GetAll
- GetAllSeq
- GetOr (Option)
- GetOr (PositionlArgs)
- GetOrFunc
- InputInfo.Env
- InputInfo.Help
- InputInfo.Long
- InputInfo.Required (Option)
- InputInfo.Required (PostionalArgument)
- InputInfo.Short
- InputInfo.ShortOnly
- InputInfo.WithParser
- InputInfo.WithValueName (Option)
- InputInfo.WithValueName (PositionalArgument)
- Lookup (Option)
- Lookup (PositionalArgs)
- NewFileParser
- NewTimeParser
- ParseDuration
- ParseURL
Constants ¶
This section is empty.
Variables ¶
var DefaultHelpInput = NewBoolOpt("help"). Short('h'). Help("Show this help message and exit."). WithHelpGen(DefaultHelpGenerator)
var DefaultVersionOpt = NewVersionOpt('v', "version", VersionOptConfig{
HelpBlurb: "Print the build info version and exit",
})
var ErrNoSubcmd = errors.New("missing subcommand")
Functions ¶
func DefaultFullHelp ¶
func DefaultFullHelp(c *CommandInfo) string
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). Opt(cli.NewOpt("aa").Env("AA").Default("def").Help("an option")). Opt(cli.NewOpt("bb"). Help("another option that is required and has a really long blurb to show how it will be wrapped"). Required()). Arg(cli.NewArg("cc").Help("a positional argument")). Opt(cli.NewBoolOpt("h"). Help("will show how this command looks in the default full help message"). WithHelpGen(func(_ cli.Input, c *cli.CommandInfo) string { return cli.DefaultFullHelp(c) })) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - an example command usage: example [options] [arguments] options: --aa <arg> an option [default: def] [env: AA] --bb <arg> (required) another option that is required and has a really long blurb to show how it will be wrapped -h will show how this command looks in the default full help message arguments: [cc] a positional argument
func DefaultHelpGenerator ¶
func DefaultHelpGenerator(src Input, c *CommandInfo) string
DefaultHelpGenerator will use DefaultShortHelp if src is the short option, or it'll use DefaultFullHelp if the src is the long option name.
func DefaultShortHelp ¶
func DefaultShortHelp(c *CommandInfo) string
Example (Complex) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). Opt(cli.NewOpt("aa").Env("AA").Default("def").Help("an option")). Opt(cli.NewOpt("bb"). Help("another option that is required and has a really long blurb to show how it will be wrapped"). Required()). Opt(cli.NewOpt("kind-of-a-long-name"). Help("due to this option's name, the blurbs for each option on this command " + "will begin on their own non-indented lines")). Arg(cli.NewArg("posarg1").Required().Help("a required positional argument")). Arg(cli.NewArg("posarg2").Env("PA2").Help("an optional positional argument")). Opt(cli.NewBoolOpt("h"). Help("will show the default short help message"). WithHelpGen(func(_ cli.Input, c *cli.CommandInfo) string { return cli.DefaultShortHelp(c) })) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - an example command usage: example [options] [arguments] options: --aa <arg> an option (default: def) [$AA] --bb <arg> another option that is required and has a really long blurb to show how it will be wrapped (required) -h will show the default short help message --kind-of-a-long-name <arg> due to this option's name, the blurbs for each option on this command will begin on their own non-indented lines arguments: <posarg1> a required positional argument (required) [posarg2] an optional positional argument [$PA2]
Example (Simple) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). Opt(cli.NewOpt("aa").Short('a').Env("AA").Default("def").Help("an option")). Opt(cli.NewOpt("bb").Short('b').Required().Help("another option")). Arg(cli.NewArg("cc").Required().Help("a required positional argument")). Arg(cli.NewArg("dd").Env("PA2").Help("an optional positional argument")). Opt(cli.NewBoolOpt("h"). Help("will show the default short help message"). WithHelpGen(func(_ cli.Input, c *cli.CommandInfo) string { return cli.DefaultShortHelp(c) })) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - an example command usage: example [options] [arguments] options: -a, --aa <arg> an option (default: def) [$AA] -b, --bb <arg> another option (required) -h will show the default short help message arguments: <cc> a required positional argument (required) [dd] an optional positional argument [$PA2]
Example (SimpleWithSubcommands) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). Opt(cli.NewOpt("aa").Short('a').Env("AA").Default("def").Help("an option")). Opt(cli.NewOpt("bb").Short('b').Required().Help("another option")). Subcmd(cli.NewCmd("subcommand1").Help("a subcommand")). Subcmd(cli.NewCmd("subcommand2").Help("another subcommand")). Opt(cli.NewBoolOpt("h"). Help("will show the default short help message"). WithHelpGen(func(_ cli.Input, c *cli.CommandInfo) string { return cli.DefaultShortHelp(c) })) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - an example command usage: example [options] <command> options: -a, --aa <arg> an option (default: def) [$AA] -b, --bb <arg> another option (required) -h will show the default short help message commands: subcommand1 a subcommand subcommand2 another subcommand
func Fatal ¶ added in v0.5.0
Fatal logs the given value to Stderr prefixed by "error: " and then exits the program with the given code.
func Get ¶
Get gets the parsed input value with the given id in the given Command and converts the value to the given type T through an untested type assertion. This function will panic if the value isn't found or if the value can't be converted to type T. To check whether the value is found instead of panicking, see Lookup.
Example (Option) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a")). Opt(cli.NewOpt("b")). ParseTheseOrExit("-b=hello") // The following line would panic because 'a' isn't present. // a := cli.Get[string](c, "a") b := cli.Get[string](c, "b") fmt.Printf("b: %q\n", b) }
Output: b: "hello"
Example (PositionalArgs) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Arg(cli.NewArg("a")). Arg(cli.NewArg("b")). ParseTheseOrExit("hello") // The following line would panic because 'a' isn't present. // b := cli.Get[string](c, "b") a := cli.Get[string](c, "a") fmt.Printf("a: %q\n", a) }
Output: a: "hello"
func GetAll ¶ added in v0.3.0
GetAll returns all parsed values present for the given id. It converts each value to the given type T through an untested type assertion (so this will panic if any value found can't be converted to type T).
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewIntOpt("a").Default("0")). ParseTheseOrExit("-a", "1", "-a", "2", "-a", "3") a := cli.GetAll[int](c, "a") fmt.Printf("%+#v\n", a) }
Output: []int{0, 1, 2, 3}
func GetAllSeq ¶ added in v0.3.0
GetAllSeq returns an iterator over each parsed value that has the given id. The iterator yields the same values that would be returned by GetAll(c, id) but without constructing the slice.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a").Default("Lorem")). ParseTheseOrExit( "-a", "ipsum", "-a", "dolor", "-a", "sit", "-a", "amet") for str := range cli.GetAllSeq[string](c, "a") { fmt.Printf("%v\n", str) } }
Output: Lorem ipsum dolor sit amet
func GetOr ¶
GetOr looks for a parsed input value with the given id in the given Command and converts the value to the given type T through an untested type assertion (so this will panic if the value is found but can't be converted to type T). If the value isn't found, the given fallback value will be returned. To check whether the value is found instead of using a fallback value, see Lookup.
Example (Option) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a")). Opt(cli.NewOpt("b")). ParseTheseOrExit("-a=hello") a := cli.Get[string](c, "a") b := cli.GetOr(c, "b", "world") fmt.Printf("a: %q\n", a) fmt.Printf("b: %q\n", b) }
Output: a: "hello" b: "world"
Example (PositionlArgs) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Arg(cli.NewArg("a")). Arg(cli.NewArg("b")). ParseTheseOrExit("hello") a := cli.Get[string](c, "a") b := cli.GetOr(c, "b", "world") fmt.Printf("a: %q\n", a) fmt.Printf("b: %q\n", b) }
Output: a: "hello" b: "world"
func GetOrFunc ¶ added in v0.3.0
GetOrFunc is like GetOr in that it looks for a parsed input value with the given id in the given Command and converts the value to the given type T through an untested type assertion (so this will panic if the value is found but can't be converted to type T). However, if the value isn't found, it will run the provided function fn in order to create and return the fallback value. To check whether the value is found instead of using a fallback, see Lookup.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a")). Opt(cli.NewOpt("b")). ParseTheseOrExit("-a", "hello") a := cli.GetOr(c, "a", "") b := cli.GetOrFunc(c, "b", func() string { return "world" }) fmt.Printf("a: %q\n", a) fmt.Printf("b: %q\n", b) }
Output: a: "hello" b: "world"
func Lookup ¶
Lookup looks for a parsed input value with the given id in the given Command and converts the value to the given type T through an untested type assertion (so this will panic if the value is found and can't be converted to type T). So if the input is present, the typed value will be returned and the boolean will be true. Otherwise, the zero value of type T will be returned and the boolean will be false.
Example (Option) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a")). Opt(cli.NewOpt("b")). ParseTheseOrExit("-b=hello") a, hasA := cli.Lookup[string](c, "a") b, hasB := cli.Lookup[string](c, "b") fmt.Printf("a: %q, %v\n", a, hasA) fmt.Printf("b: %q, %v\n", b, hasB) }
Output: a: "", false b: "hello", true
Example (PositionalArgs) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Arg(cli.NewArg("a")). Arg(cli.NewArg("b")). ParseTheseOrExit("hello") a, hasA := cli.Lookup[string](c, "a") b, hasB := cli.Lookup[string](c, "b") fmt.Printf("a: %q, %v\n", a, hasA) fmt.Printf("b: %q, %v\n", b, hasB) }
Output: a: "hello", true b: "", false
func ParseBool ¶
ParseBool returns the boolean value represented by the given string. See strconv.ParseBool for more info.
func ParseDuration ¶
ParseDuration uses the standard library time.ParseDuration function to parse and return the time.Duration value represented by the given string.
Example ¶
package main import ( "fmt" "time" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("d").WithParser(cli.ParseDuration)) c := in.ParseTheseOrExit("-d", "1h2m3s") fmt.Println(cli.Get[time.Duration](c, "d")) _, err := in.ParseThese("-d", "not_a_duration") fmt.Println(err) }
Output: 1h2m3s parsing option 'd': time: invalid duration "not_a_duration"
func ParseFloat32 ¶
ParseFloat32 returns the float32 value represented by the given string. It unwraps any strconv.NumError returned by strconv.ParseFloat for a slightly cleaner error message.
func ParseFloat64 ¶
ParseFloat64 returns the float64 value represented by the given string. It unwraps any strconv.NumError returned by strconv.ParseFloat for a slightly cleaner error message.
func ParseInt ¶
ParseInt returns the int value represented by the given string. It unwraps any strconv.NumError returned by strconv.ParseInt for a slightly cleaner error message.
func ParseURL ¶
ParseURL uses the standard library url.Parse function to parse and return the *url.URL value represented by the given string.
Example ¶
package main import ( "fmt" "net/url" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("u").WithParser(cli.ParseURL)) c := in.ParseTheseOrExit("-u", "https://pkg.go.dev/github.com/steverusso/cli#ParseURL") fmt.Println(cli.Get[*url.URL](c, "u")) _, err := in.ParseThese("-u", "b@d://.com") fmt.Println(err) }
Output: https://pkg.go.dev/github.com/steverusso/cli#ParseURL parsing option 'u': parse "b@d://.com": first path segment in URL cannot contain colon
func ParseUint ¶
ParseUint returns the uint value represented by the given string. It unwraps any strconv.NumError returned by strconv.ParseUint for a slightly cleaner error message.
Types ¶
type CommandInfo ¶
type CommandInfo struct { Name string Path []string HelpUsage []string HelpBlurb string HelpExtra string Opts []InputInfo Args []InputInfo Subcmds []CommandInfo // contains filtered or unexported fields }
func New ¶ added in v0.3.0
func New(name ...string) CommandInfo
New is intented to initialize a new root command. If no name is provided, it will use runtime information to get the module name and use that for the command's name. Anything more than a single name provided is ignored.
func NewCmd ¶
func NewCmd(name string) CommandInfo
func (CommandInfo) Arg ¶
func (c CommandInfo) Arg(pa InputInfo) CommandInfo
Arg adds pa as a positional argument to this CommandInfo. This method will panic if this command already has one or more subcommands (because positional arguments and subcommands are mutually exclusive), or if pa has any option names set, or if pa is required but any previously positional argument is not required (because required positional arguments cannot come after optional ones).
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Arg(cli.NewArg("name")). ParseTheseOrExit("alice") fmt.Println(cli.Get[string](c, "name")) }
Output: alice
func (CommandInfo) ExtraHelp ¶
func (c CommandInfo) ExtraHelp(extra string) CommandInfo
ExtraHelp adds an "overview" section to the Command's help message. This is typically for longer-form content that wouldn't fit well within the 1-2 sentence "blurb."
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). ExtraHelp("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.") _, err := in.ParseThese("--help") fmt.Println(err) }
Output: example - an example command overview: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. usage: example [options] options: -h, --help Show this help message and exit.
func (CommandInfo) Help ¶
func (c CommandInfo) Help(blurb string) CommandInfo
func (CommandInfo) Opt ¶
func (c CommandInfo) Opt(o InputInfo) CommandInfo
Opt adds o as an option to this CommandInfo. This method will panic if the option has neither a long or short name set (this should never happen when using the builder pattern starting with the NewOpt function or its siblings).
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { c := cli.New(). Opt(cli.NewOpt("a")). ParseTheseOrExit("-a", "hello") fmt.Println(cli.Get[string](c, "a")) }
Output: hello
func (*CommandInfo) Parse ¶
func (in *CommandInfo) Parse() (*Command, error)
ParseOrExit will parse input based on this CommandInfo. If no function arguments are provided, the os.Args will be used.
func (CommandInfo) ParseOrExit ¶
func (in CommandInfo) ParseOrExit() *Command
ParseOrExit will parse input based on this CommandInfo. If help was requested, it will print the help message and exit the program successfully (status code 0). If there is any other error, it will print the error and exit the program with failure (status code 1). The input parameter semantics are the same as CommandInfo.Parse.
func (*CommandInfo) ParseThese ¶ added in v0.5.0
func (in *CommandInfo) ParseThese(args ...string) (*Command, error)
func (CommandInfo) ParseTheseOrExit ¶ added in v0.5.0
func (in CommandInfo) ParseTheseOrExit(args ...string) *Command
func (CommandInfo) Subcmd ¶
func (c CommandInfo) Subcmd(sc CommandInfo) CommandInfo
Subcmd adds the given CommandInfo sc as a subcommand under c. This function will panic if c already has at least one positional argument because commands cannot contain both positional arguments and subcommands simultaneously.
func (CommandInfo) Usage ¶
func (c CommandInfo) Usage(lines ...string) CommandInfo
Usage overrides the default "usage" lines in the command's help message. These are intended to show the user some different ways to invoke this command using whatever combinations of options / arguments / subcommands.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("an example command"). Usage( "example [--aa <arg>]", "example [-h]", ). Opt(cli.NewOpt("aa").Help("an option")) _, err := in.ParseThese("--help") fmt.Println(err) }
Output: example - an example command usage: example [--aa <arg>] example [-h] options: --aa <arg> an option -h, --help Show this help message and exit.
type HelpGenerator ¶
type HelpGenerator = func(Input, *CommandInfo) string
HelpGenerator describes any function that will return a help message based on the Input that triggered it and the CommandInfo of which it is a member. See DefaultHelpGenerator for an example.
type HelpOrVersionRequested ¶ added in v0.5.0
type HelpOrVersionRequested struct {
Msg string
}
func (HelpOrVersionRequested) Error ¶ added in v0.5.0
func (h HelpOrVersionRequested) Error() string
type Input ¶
type Input struct { Value any ID string RawValue string From ParsedFrom }
Input is a parsed option value or positional argument value along with other information such as the input ID it corresponds to and where it was parsed from.
type InputInfo ¶
type InputInfo struct { ID string NameShort byte NameLong string HelpBlurb string EnvVar string IsBoolOpt bool IsRequired bool StrDefault string HasStrDefault bool ValueName string ValueParser ValueParser HelpGen HelpGenerator Versioner Versioner }
func NewArg ¶
NewArg returns a new positional argument input. By default, the arg's display name will be the provided id, but this can be overidden with InputInfo.WithValueName method.
func NewBoolOpt ¶
NewBoolOpt returns a new boolean option. If no value is provided to this option when parsing, it will have a "parsed" value of true. If any value is provided, the ParseBool value parser is used. Any other parser set by the user for this option will be ignored.
func NewFloat32Opt ¶
NewFloat32Opt returns a new option that uses the ParseFloat32 value parser.
func NewFloat64Opt ¶
NewFloat64Opt returns a new option that uses the ParseFloat64 value parser.
func NewOpt ¶
NewOpt returns a new non-boolean option with no parser, which means it will just receive the raw string of any provided value. If id is more than a single character long, it will be this option's long name. If id is only a single character, it will be this option's short name instead. In either case, the long name can be reset using the InputInfo.Long method.
func NewUintOpt ¶
NewUintOpt returns a new option that uses the ParseUint value parser.
func NewVersionOpt ¶ added in v0.5.0
func NewVersionOpt(short byte, long string, cfg VersionOptConfig) InputInfo
NewVersionOpt returns a input that will the Versioner field set to a function that outputs information based on the given configuration values. At a minimum, the default version message will always contain the Go module version obtained from debug.BuildInfo. Version inputs, similar to help inputs, cause this library's parsing to return a HelpOrVersionRequested error. This function will panic if the given long name is empty and the given short name is either 0 or '-'.
func (InputInfo) Env ¶
Env sets the name of the environment variable for this InputInfo. The parser will parse the value of that environment variable for this input if it is set.
Example ¶
package main import ( "fmt" "os" "github.com/steverusso/cli" ) func main() { os.Setenv("FLAG", "hello") c := cli.New(). Opt(cli.NewOpt("flag").Env("FLAG")). ParseTheseOrExit() fmt.Println(cli.Get[string](c, "flag")) }
Output: hello
func (InputInfo) Help ¶
Help sets the brief help blurb for this option or positional argument.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("example program"). Opt(cli.NewOpt("aa").Help("a short one or two sentence blurb")) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - example program usage: example [options] options: --aa <arg> a short one or two sentence blurb -h, --help Show this help message and exit.
func (InputInfo) Long ¶
Long sets the option long name to the given name. Since an option's long name will be the input ID by default, this method is really only necessary when the long name must differ from the input ID.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("example program"). Opt(cli.NewOpt("id1").Help("long name is the id by default")). Opt(cli.NewOpt("id2").Long("long-name").Help("long name is set to something other than the id")) _, err := in.ParseThese("-h") fmt.Println(err) }
Output: example - example program usage: example [options] options: -h, --help Show this help message and exit. --id1 <arg> long name is the id by default --long-name <arg> long name is set to something other than the id
func (InputInfo) Required ¶
Required marks this InputInfo as required, which means an error will be returned when parsing if a value is not provided. If this is a positional argument, it must be added to a command before any optional positional arguments. Required options, however, can be added in any order. See the "Command Line Syntax" section at the top of the docs
Example (Option) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("a")). Opt(cli.NewOpt("b").Required()) c, _ := in.ParseThese("-a", "hello", "-b", "world") fmt.Println( cli.Get[string](c, "a"), cli.Get[string](c, "b"), ) _, err := in.ParseThese() fmt.Println(err) }
Output: hello world missing the following required options: -b
Example (PostionalArgument) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New(). Arg(cli.NewArg("a").Required()). Arg(cli.NewArg("b")) c, _ := in.ParseThese("hello", "world") fmt.Println( cli.Get[string](c, "a"), cli.Get[string](c, "b"), ) _, err := in.ParseThese() fmt.Println(err) }
Output: hello world missing the following required arguments: a
func (InputInfo) Short ¶
Short sets this option's short name to the given character. In order to create an option that has a short name but no long name, see InputInfo.ShortOnly.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("flag").Short('f')) c1 := in.ParseTheseOrExit("-f", "hello") fmt.Println(cli.Get[string](c1, "flag")) c2 := in.ParseTheseOrExit("--flag", "world") fmt.Println(cli.Get[string](c2, "flag")) }
Output: hello world
func (InputInfo) ShortOnly ¶
ShortOnly sets this option's short name to the given character and removes any long name it may have had at this point. In order to create an option that has both a short and long name, see InputInfo.Short. Use InputInfo.Long to add a long name back.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("flag").ShortOnly('f')) c := in.ParseTheseOrExit("-f", "hello") fmt.Println(cli.Get[string](c, "flag")) _, err := in.ParseThese("--flag", "helloworld") fmt.Println(err) }
Output: hello unknown option '--flag'
func (InputInfo) WithHelpGen ¶
func (in InputInfo) WithHelpGen(hg HelpGenerator) InputInfo
func (InputInfo) WithParser ¶
func (in InputInfo) WithParser(vp ValueParser) InputInfo
WithParser sets the InputInfo's parser to the given ValueParser. This will override any parser that has been set up until this point. Providing nil as the parser will restore the default behavior of just using the plain string value when this InputInfo is parsed.
Example ¶
package main import ( "fmt" "image" "strconv" "strings" "github.com/steverusso/cli" ) func main() { pointParser := func(s string) (any, error) { comma := strings.IndexByte(s, ',') x, _ := strconv.Atoi(s[:comma]) y, _ := strconv.Atoi(s[comma+1:]) return image.Point{X: x, Y: y}, nil } c := cli.New(). Opt(cli.NewOpt("aa").WithParser(pointParser)). ParseTheseOrExit("--aa", "3,7") fmt.Printf("%+#v\n", cli.Get[image.Point](c, "aa")) }
Output: image.Point{X:3, Y:7}
func (InputInfo) WithValueName ¶
WithValueName sets the display name of this InputInfo's argument value. For non-boolean options, it's the argument of the option. For positional arguments, it's the argument name itself.
Example (Option) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("example program"). Opt(cli.NewOpt("aa").WithValueName("str").Help("it says '<str>' above instead of '<arg>'")) _, err := in.ParseThese("--help") fmt.Println(err) }
Output: example - example program usage: example [options] options: --aa <str> it says '<str>' above instead of '<arg>' -h, --help Show this help message and exit.
Example (PositionalArgument) ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New("example"). Help("example program"). Arg(cli.NewArg("aa").WithValueName("filename").Help("it says '[filename]' above instead of '[aa]'")) _, err := in.ParseThese("--help") fmt.Println(err) }
Output: example - example program usage: example [options] [arguments] options: -h, --help Show this help message and exit. arguments: [filename] it says '[filename]' above instead of '[aa]'
func (InputInfo) WithVersioner ¶ added in v0.5.0
WithVersioner will set this input's Versioner to the given Versioner. This will turn this input into one that, similar to help inputs, causes the parsing to return a HelpOrVersionRequested error. See NewVersionOpt for a convenient way to create version inputs.
type MissingArgsError ¶
type MissingArgsError struct{ Names []string }
func (MissingArgsError) Error ¶
func (mae MissingArgsError) Error() string
func (MissingArgsError) Is ¶
func (mae MissingArgsError) Is(err error) bool
type MissingOptionValueError ¶
type MissingOptionValueError struct{ Name string }
func (MissingOptionValueError) Error ¶
func (mov MissingOptionValueError) Error() string
type MissingOptionsError ¶
type MissingOptionsError struct{ Names []string }
func (MissingOptionsError) Error ¶
func (moe MissingOptionsError) Error() string
func (MissingOptionsError) Is ¶
func (moe MissingOptionsError) Is(err error) bool
type ParsedFrom ¶
type ParsedFrom struct { Env string // Came from this env var's name. Opt string // Came from this provided option name. Arg int // Appeared as the nth positional argument starting from 1. Default bool // Came from a provided default value. }
ParsedFrom describes where an Input is parsed from. The place it came from will be the only non-zero field of this struct.
type UnknownOptionError ¶
type UnknownOptionError struct{ Name string }
func (UnknownOptionError) Error ¶
func (uoe UnknownOptionError) Error() string
type UnknownSubcmdError ¶
type UnknownSubcmdError struct{ Name string }
func (UnknownSubcmdError) Error ¶
func (usce UnknownSubcmdError) Error() string
type ValueParser ¶
ValueParser describes any function that takes a string and returns some type or an error. This is the signature of any input value parser. See ParseBool, ParseInt, and the other provided parsers for some examples.
func NewFileParser ¶
func NewFileParser(vp ValueParser) ValueParser
NewFileParser returns a ValueParser that will treat an input string as a file path and use given parser to parse the content of the file at that path.
Example ¶
package main import ( "fmt" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("i").WithParser(cli.NewFileParser(cli.ParseInt))). Opt(cli.NewOpt("s").WithParser(cli.NewFileParser(nil))) c, _ := in.ParseThese( "-i", "testdata/sample_int", "-s", "testdata/sample_int", ) fmt.Println(cli.Get[int](c, "i")) fmt.Printf("%q\n", cli.Get[string](c, "s")) _, err := in.ParseThese("-i", "testdata/sample_empty") fmt.Println(err) _, err = in.ParseThese("-i", "path_that_doesnt_exist") fmt.Println(err) }
Output: 12345 "12345" parsing option 'i': invalid syntax parsing option 'i': open path_that_doesnt_exist: no such file or directory
func NewTimeParser ¶
func NewTimeParser(layout string) ValueParser
NewTimeParser returns a ValueParser that will use the standard library time.Parse function with the given layout string to parse and return a time.Time from a given string.
Example ¶
package main import ( "fmt" "time" "github.com/steverusso/cli" ) func main() { in := cli.New(). Opt(cli.NewOpt("t").WithParser(cli.NewTimeParser("2006-01-02"))) c := in.ParseTheseOrExit("-t", "2025-04-12") fmt.Println(cli.Get[time.Time](c, "t")) _, err := in.ParseThese("-t", "hello") fmt.Println(err) }
Output: 2025-04-12 00:00:00 +0000 UTC parsing option 't': parsing time "hello" as "2006-01-02": cannot parse "hello" as "2006"
type VersionOptConfig ¶ added in v0.5.0
VersionOptConfig is used to pass customization values to NewVersionOpt.