package arg import ( "fmt" "net" "net/mail" "net/url" "os" "strings" "time" ) func split(s string) []string { return strings.Split(s, " ") } // This example demonstrates basic usage func Example() { // These are the args you would pass in on the command line os.Args = split("./example --foo=hello --bar") var args struct { Foo string Bar bool } MustParse(&args) fmt.Println(args.Foo, args.Bar) // output: hello true } // This example demonstrates arguments that have default values func Example_defaultValues() { // These are the args you would pass in on the command line os.Args = split("./example") var args struct { Foo string `default:"abc"` } MustParse(&args) fmt.Println(args.Foo) // output: abc } // This example demonstrates arguments that are required func Example_requiredArguments() { // These are the args you would pass in on the command line os.Args = split("./example --foo=abc --bar") var args struct { Foo string `arg:"required"` Bar bool } MustParse(&args) fmt.Println(args.Foo, args.Bar) // output: abc true } // This example demonstrates positional arguments func Example_positionalArguments() { // These are the args you would pass in on the command line os.Args = split("./example in out1 out2 out3") var args struct { Input string `arg:"positional"` Output []string `arg:"positional"` } MustParse(&args) fmt.Println("In:", args.Input) fmt.Println("Out:", args.Output) // output: // In: in // Out: [out1 out2 out3] } // This example demonstrates arguments that have multiple values func Example_multipleValues() { // The args you would pass in on the command line os.Args = split("./example --database localhost --ids 1 2 3") var args struct { Database string IDs []int64 } MustParse(&args) fmt.Printf("Fetching the following IDs from %s: %v", args.Database, args.IDs) // output: Fetching the following IDs from localhost: [1 2 3] } // This example demonstrates arguments with keys and values func Example_mappings() { // The args you would pass in on the command line os.Args = split("./example --userids john=123 mary=456") var args struct { UserIDs map[string]int } MustParse(&args) fmt.Println(args.UserIDs) // output: map[john:123 mary:456] } type commaSeparated struct { M map[string]string } func (c *commaSeparated) UnmarshalText(b []byte) error { c.M = make(map[string]string) for _, part := range strings.Split(string(b), ",") { pos := strings.Index(part, "=") if pos == -1 { return fmt.Errorf("error parsing %q, expected format key=value", part) } c.M[part[:pos]] = part[pos+1:] } return nil } // This example demonstrates arguments with keys and values separated by commas func Example_mappingWithCommas() { // The args you would pass in on the command line os.Args = split("./example --values one=two,three=four") var args struct { Values commaSeparated } MustParse(&args) fmt.Println(args.Values.M) // output: map[one:two three:four] } // This eample demonstrates multiple value arguments that can be mixed with // other arguments. func Example_multipleMixed() { os.Args = split("./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3") var args struct { Commands []string `arg:"-c,separate"` Files []string `arg:"-f,separate"` Databases []string `arg:"positional"` } MustParse(&args) fmt.Println("Commands:", args.Commands) fmt.Println("Files:", args.Files) fmt.Println("Databases:", args.Databases) // output: // Commands: [cmd1 cmd2 cmd3] // Files: [file1 file2 file3] // Databases: [db1 db2 db3] } // This example shows the usage string generated by go-arg func Example_helpText() { // These are the args you would pass in on the command line os.Args = split("./example --help") var args struct { Input string `arg:"positional,required"` Output []string `arg:"positional"` Verbose bool `arg:"-v" help:"verbosity level"` Dataset string `help:"dataset to use"` Optimize int `arg:"-O,--optim" help:"optimization level"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example [--verbose] [--dataset DATASET] [--optim OPTIM] INPUT [OUTPUT [OUTPUT ...]] // // Positional arguments: // INPUT // OUTPUT // // Options: // --verbose, -v verbosity level // --dataset DATASET dataset to use // --optim OPTIM, -O OPTIM // optimization level // --help, -h display this help and exit } // This example shows the usage string generated by go-arg with customized placeholders func Example_helpPlaceholder() { // These are the args you would pass in on the command line os.Args = split("./example --help") var args struct { Input string `arg:"positional,required" placeholder:"SRC"` Output []string `arg:"positional" placeholder:"DST"` Optimize int `arg:"-O" help:"optimization level" placeholder:"LEVEL"` MaxJobs int `arg:"-j" help:"maximum number of simultaneous jobs" placeholder:"N"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]] // Positional arguments: // SRC // DST // Options: // --optimize LEVEL, -O LEVEL // optimization level // --maxjobs N, -j N maximum number of simultaneous jobs // --help, -h display this help and exit } // This example shows the usage string generated by go-arg when using subcommands func Example_helpTextWithSubcommand() { // These are the args you would pass in on the command line os.Args = split("./example --help") type getCmd struct { Item string `arg:"positional" help:"item to fetch"` } type listCmd struct { Format string `help:"output format"` Limit int } var args struct { Verbose bool Get *getCmd `arg:"subcommand" help:"fetch an item and print it"` List *listCmd `arg:"subcommand" help:"list available items"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example [--verbose] [] // // Options: // --verbose // --help, -h display this help and exit // // Commands: // get fetch an item and print it // list list available items } // This example shows the usage string generated by go-arg when using subcommands func Example_helpTextWhenUsingSubcommand() { // These are the args you would pass in on the command line os.Args = split("./example get --help") type getCmd struct { Item string `arg:"positional,required" help:"item to fetch"` } type listCmd struct { Format string `help:"output format"` Limit int } var args struct { Verbose bool Get *getCmd `arg:"subcommand" help:"fetch an item and print it"` List *listCmd `arg:"subcommand" help:"list available items"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example get ITEM // // Positional arguments: // ITEM item to fetch // // Global options: // --verbose // --help, -h display this help and exit } // This example shows how to print help for an explicit subcommand func Example_writeHelpForSubcommand() { // These are the args you would pass in on the command line os.Args = split("./example get --help") type getCmd struct { Item string `arg:"positional" help:"item to fetch"` } type listCmd struct { Format string `help:"output format"` Limit int } var args struct { Verbose bool Get *getCmd `arg:"subcommand" help:"fetch an item and print it"` List *listCmd `arg:"subcommand" help:"list available items"` } // This is only necessary when running inside golang's runnable example harness exit := func(int) {} p, err := NewParser(Config{Exit: exit}, &args) if err != nil { fmt.Println(err) os.Exit(1) } err = p.WriteHelpForSubcommand(os.Stdout, "list") if err != nil { fmt.Println(err) os.Exit(1) } // output: // Usage: example list [--format FORMAT] [--limit LIMIT] // // Options: // --format FORMAT output format // --limit LIMIT // // Global options: // --verbose // --help, -h display this help and exit } // This example shows how to print help for a subcommand that is nested several levels deep func Example_writeHelpForSubcommandNested() { // These are the args you would pass in on the command line os.Args = split("./example get --help") type mostNestedCmd struct { Item string } type nestedCmd struct { MostNested *mostNestedCmd `arg:"subcommand"` } type topLevelCmd struct { Nested *nestedCmd `arg:"subcommand"` } var args struct { TopLevel *topLevelCmd `arg:"subcommand"` } // This is only necessary when running inside golang's runnable example harness exit := func(int) {} p, err := NewParser(Config{Exit: exit}, &args) if err != nil { fmt.Println(err) os.Exit(1) } err = p.WriteHelpForSubcommand(os.Stdout, "toplevel", "nested", "mostnested") if err != nil { fmt.Println(err) os.Exit(1) } // output: // Usage: example toplevel nested mostnested [--item ITEM] // // Options: // --item ITEM // --help, -h display this help and exit } // This example shows the error string generated by go-arg when an invalid option is provided func Example_errorText() { // These are the args you would pass in on the command line os.Args = split("./example --optimize INVALID") var args struct { Input string `arg:"positional,required"` Output []string `arg:"positional"` Verbose bool `arg:"-v" help:"verbosity level"` Dataset string `help:"dataset to use"` Optimize int `arg:"-O,help:optimization level"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] INPUT [OUTPUT [OUTPUT ...]] // error: error processing --optimize: strconv.ParseInt: parsing "INVALID": invalid syntax } // This example shows the error string generated by go-arg when an invalid option is provided func Example_errorTextForSubcommand() { // These are the args you would pass in on the command line os.Args = split("./example get --count INVALID") type getCmd struct { Count int } var args struct { Get *getCmd `arg:"subcommand"` } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) // output: // Usage: example get [--count COUNT] // error: error processing --count: strconv.ParseInt: parsing "INVALID": invalid syntax } // This example demonstrates use of subcommands func Example_subcommand() { // These are the args you would pass in on the command line os.Args = split("./example commit -a -m what-this-commit-is-about") type CheckoutCmd struct { Branch string `arg:"positional"` Track bool `arg:"-t"` } type CommitCmd struct { All bool `arg:"-a"` Message string `arg:"-m"` } type PushCmd struct { Remote string `arg:"positional"` Branch string `arg:"positional"` SetUpstream bool `arg:"-u"` } var args struct { Checkout *CheckoutCmd `arg:"subcommand:checkout"` Commit *CommitCmd `arg:"subcommand:commit"` Push *PushCmd `arg:"subcommand:push"` Quiet bool `arg:"-q"` // this flag is global to all subcommands } // This is only necessary when running inside golang's runnable example harness mustParseExit = func(int) {} MustParse(&args) switch { case args.Checkout != nil: fmt.Printf("checkout requested for branch %s\n", args.Checkout.Branch) case args.Commit != nil: fmt.Printf("commit requested with message \"%s\"\n", args.Commit.Message) case args.Push != nil: fmt.Printf("push requested from %s to %s\n", args.Push.Branch, args.Push.Remote) } // output: // commit requested with message "what-this-commit-is-about" } func Example_allSupportedTypes() { // These are the args you would pass in on the command line os.Args = []string{} var args struct { Bool bool Byte byte Rune rune Int int Int8 int8 Int16 int16 Int32 int32 Int64 int64 Float32 float32 Float64 float64 String string Duration time.Duration URL url.URL Email mail.Address MAC net.HardwareAddr } // go-arg supports each of the types above, as well as pointers to any of // the above and slices of any of the above. It also supports any types that // implements encoding.TextUnmarshaler. MustParse(&args) // output: } func Example_envVarOnly() { os.Args = split("./example") _ = os.Setenv("AUTH_KEY", "my_key") defer os.Unsetenv("AUTH_KEY") var args struct { AuthKey string `arg:"--,env:AUTH_KEY"` } MustParse(&args) fmt.Println(args.AuthKey) // output: my_key } func Example_envVarOnlyShouldIgnoreFlag() { os.Args = split("./example --=my_key") var args struct { AuthKey string `arg:"--,env:AUTH_KEY"` } err := Parse(&args) fmt.Println(err) // output: unknown argument --=my_key } func Example_envVarOnlyShouldIgnoreShortFlag() { os.Args = split("./example -=my_key") var args struct { AuthKey string `arg:"--,env:AUTH_KEY"` } err := Parse(&args) fmt.Println(err) // output: unknown argument -=my_key }