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=v // long form non-boolean option with value of "v" --opt v // same as above, non-boolean options can provide their value as the next command line argument -a // short form boolean option "a" -a -b // two short form boolean option "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 ¶
p := cli.NewCmd("full").
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."))).
Build().
ParseOrExit()
Index ¶
- Variables
- func DefaultFullHelp(c *CommandInfo) string
- func DefaultHelpGenerator(src Input, c *CommandInfo) string
- func DefaultShortHelp(c *CommandInfo) string
- func GetArg[T any](c *Command, id string) T
- func GetArgOr[T any](c *Command, id string, fallback T) T
- func GetOpt[T any](c *Command, id string) T
- func GetOptOr[T any](c *Command, id string, fallback T) T
- func LookupArg[T any](c *Command, id string) (T, bool)
- func LookupOpt[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(a InputInfo) CommandInfo
- func (c CommandInfo) Help(blurb string) CommandInfo
- func (c CommandInfo) HelpExtra(extra string) CommandInfo
- func (c CommandInfo) HelpUsage(lines ...string) CommandInfo
- func (c CommandInfo) Opt(o InputInfo) CommandInfo
- func (in *CommandInfo) Parse(args ...string) (*Command, error)
- func (in CommandInfo) ParseOrExit(args ...string) *Command
- func (c CommandInfo) Subcmd(sc CommandInfo) CommandInfo
- type HelpGenerator
- type HelpRequestError
- type Input
- type 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) HelpGen(hg HelpGenerator) 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) ValueName(name string) InputInfo
- func (in InputInfo) WithParser(vp ValueParser) InputInfo
- type MissingArgsError
- type MissingOptionValueError
- type MissingOptionsError
- type ParsedFrom
- type UnknownOptionError
- type UnknownSubcmdError
- type ValueParser
Examples ¶
- CommandInfo.HelpExtra
- CommandInfo.HelpUsage
- DefaultFullHelp
- DefaultShortHelp (Complex)
- DefaultShortHelp (Simple)
- DefaultShortHelp (SimpleWithSubcommands)
- GetArg
- GetArgOr
- GetOpt
- GetOptOr
- InputInfo.Short
- InputInfo.ShortOnly
- InputInfo.ValueName (Option)
- InputInfo.ValueName (PositionalArgument)
- InputInfo.WithParser
- LookupArg
- LookupOpt
- NewFileParser
- NewTimeParser
- ParseDuration
- ParseURL
Constants ¶
This section is empty.
Variables ¶
var DefaultHelpInput = NewBoolOpt("help"). Short('h'). Help("Show this help message and exit."). HelpGen(DefaultHelpGenerator)
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.NewCmd("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").
HelpGen(func(_ cli.Input, c *cli.CommandInfo) string {
return cli.DefaultFullHelp(c)
}))
_, err := in.Parse("-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.NewCmd("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("short-blurb-but-really-long-name").Help("another option")).
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").
HelpGen(func(_ cli.Input, c *cli.CommandInfo) string {
return cli.DefaultShortHelp(c)
}))
_, err := in.Parse("-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 --short-blurb-but-really-long-name <arg> another option 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.NewCmd("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").
HelpGen(func(_ cli.Input, c *cli.CommandInfo) string {
return cli.DefaultShortHelp(c)
}))
_, err := in.Parse("-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.NewCmd("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").
HelpGen(func(_ cli.Input, c *cli.CommandInfo) string {
return cli.DefaultShortHelp(c)
}))
_, err := in.Parse("-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 GetArg ¶
GetArg gets the positional argument 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 LookupArg.
Example ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Arg(cli.NewArg("a")).
Arg(cli.NewArg("b")).
ParseOrExit("hello")
// The following line would panic because 'a' isn't present.
// b := cli.GetArg[string](c, "b")
a := cli.GetArg[string](c, "a")
fmt.Printf("a: %q\n", a)
}
Output: a: "hello"
func GetArgOr ¶
GetArgOr looks for a positional argument 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). 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 LookupArg.
Example ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Arg(cli.NewArg("a")).
Arg(cli.NewArg("b")).
ParseOrExit("hello")
a := cli.GetArg[string](c, "a")
b := cli.GetArgOr(c, "b", "world")
fmt.Printf("a: %q\n", a)
fmt.Printf("b: %q\n", b)
}
Output: a: "hello" b: "world"
func GetOpt ¶
GetOpt gets the option 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 LookupOpt.
Example ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Opt(cli.NewOpt("a")).
Opt(cli.NewOpt("b")).
ParseOrExit("-b=hello")
// The following line would panic because 'a' isn't present.
// a := cli.GetOpt[string](c, "a")
b := cli.GetOpt[string](c, "b")
fmt.Printf("b: %q\n", b)
}
Output: b: "hello"
func GetOptOr ¶
GetOptOr looks for an option 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). 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 LookupOpt.
Example ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Opt(cli.NewOpt("a")).
Opt(cli.NewOpt("b")).
ParseOrExit("-a=hello")
a := cli.GetOpt[string](c, "a")
b := cli.GetOptOr(c, "b", "world")
fmt.Printf("a: %q\n", a)
fmt.Printf("b: %q\n", b)
}
Output: a: "hello" b: "world"
func LookupArg ¶
LookupArg looks for a positional argument 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 positional argument 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 ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Arg(cli.NewArg("a")).
Arg(cli.NewArg("b")).
ParseOrExit("hello")
a, hasA := cli.LookupArg[string](c, "a")
b, hasB := cli.LookupArg[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 LookupOpt ¶
LookupOpt looks for an option 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 option 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 ¶
package main
import (
"fmt"
"github.com/steverusso/cli"
)
func main() {
c := cli.NewCmd("example").
Opt(cli.NewOpt("a")).
Opt(cli.NewOpt("b")).
ParseOrExit("-b=hello")
a, hasA := cli.LookupOpt[string](c, "a")
b, hasB := cli.LookupOpt[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
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.NewCmd("example").
Opt(cli.NewOpt("d").WithParser(cli.ParseDuration))
c := in.ParseOrExit("-d", "1h2m3s")
fmt.Println(cli.GetOpt[time.Duration](c, "d"))
_, err := in.Parse("-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.NewCmd("example").
Opt(cli.NewOpt("u").WithParser(cli.ParseURL))
c := in.ParseOrExit("-u", "https://pkg.go.dev/github.com/steverusso/cli#ParseURL")
fmt.Println(cli.GetOpt[*url.URL](c, "u"))
_, err := in.Parse("-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 {
// contains filtered or unexported fields
}
func NewCmd ¶
func NewCmd(name string) CommandInfo
func (CommandInfo) Arg ¶
func (c CommandInfo) Arg(a InputInfo) CommandInfo
func (CommandInfo) Help ¶
func (c CommandInfo) Help(blurb string) CommandInfo
func (CommandInfo) HelpExtra ¶
func (c CommandInfo) HelpExtra(extra string) CommandInfo
HelpExtra 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.NewCmd("example").
Help("an example command").
HelpExtra("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.Parse("--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) HelpUsage ¶
func (c CommandInfo) HelpUsage(lines ...string) CommandInfo
HelpUsage 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.NewCmd("example").
Help("an example command").
HelpUsage(
"example [--aa <arg>]",
"example [-h]",
).
Opt(cli.NewOpt("aa").Help("an option"))
_, err := in.Parse("--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.
func (CommandInfo) Opt ¶
func (c CommandInfo) Opt(o InputInfo) CommandInfo
func (*CommandInfo) Parse ¶
func (in *CommandInfo) Parse(args ...string) (*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(args ...string) *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) Subcmd ¶
func (c CommandInfo) Subcmd(sc CommandInfo) CommandInfo
type HelpGenerator ¶
type HelpGenerator = func(Input, *CommandInfo) string
type HelpRequestError ¶
type HelpRequestError struct {
HelpMsg string
}
func (HelpRequestError) Error ¶
func (h HelpRequestError) Error() string
type InputInfo ¶
type InputInfo struct {
// contains filtered or unexported fields
}
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.ValueName 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 (InputInfo) HelpGen ¶
func (in InputInfo) HelpGen(hg HelpGenerator) InputInfo
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.NewCmd("example").
Opt(cli.NewOpt("flag").Short('f'))
c1 := in.ParseOrExit("-f", "hello")
fmt.Println(cli.GetOpt[string](c1, "flag"))
c2 := in.ParseOrExit("--flag", "world")
fmt.Println(cli.GetOpt[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.NewCmd("example").
Opt(cli.NewOpt("flag").ShortOnly('f'))
c := in.ParseOrExit("-f", "hello")
fmt.Println(cli.GetOpt[string](c, "flag"))
_, err := in.Parse("--flag", "helloworld")
fmt.Println(err)
}
Output: hello unknown option '--flag'
func (InputInfo) ValueName ¶
ValueName 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.NewCmd("example").
Help("example program").
Opt(cli.NewOpt("aa").ValueName("str").Help("it says '<str>' above instead of '<arg>'"))
_, err := in.Parse("--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.NewCmd("example").
Help("example program").
Arg(cli.NewArg("aa").ValueName("filename").Help("it says '[filename]' above instead of '[aa]'"))
_, err := in.Parse("--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) 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.NewCmd("example").
Opt(cli.NewOpt("aa").WithParser(pointParser)).
ParseOrExit("--aa", "3,7")
fmt.Printf("%+#v\n", cli.GetOpt[image.Point](c, "aa"))
}
Output: image.Point{X:3, Y:7}
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 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 ¶
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.NewCmd("example").
Opt(cli.NewOpt("i").WithParser(cli.NewFileParser(cli.ParseInt))).
Opt(cli.NewOpt("s").WithParser(cli.NewFileParser(nil)))
c := in.ParseOrExit(
"-i", "testdata/sample_int",
"-s", "testdata/sample_int",
)
fmt.Println(cli.GetOpt[int](c, "i"))
fmt.Printf("%q\n", cli.GetOpt[string](c, "s"))
_, err := in.Parse("-i", "testdata/sample_empty")
fmt.Println(err)
_, err = in.Parse("-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.NewCmd("example").
Opt(cli.NewOpt("t").WithParser(cli.NewTimeParser("2006-01-02")))
c := in.ParseOrExit("-t", "2025-04-12")
fmt.Println(cli.GetOpt[time.Time](c, "t"))
_, err := in.Parse("-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"