github.com/alexflint/go-arg@v1.4.3/example_test.go (about)

     1  package arg
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/mail"
     7  	"net/url"
     8  	"os"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  func split(s string) []string {
    14  	return strings.Split(s, " ")
    15  }
    16  
    17  // This example demonstrates basic usage
    18  func Example() {
    19  	// These are the args you would pass in on the command line
    20  	os.Args = split("./example --foo=hello --bar")
    21  
    22  	var args struct {
    23  		Foo string
    24  		Bar bool
    25  	}
    26  	MustParse(&args)
    27  	fmt.Println(args.Foo, args.Bar)
    28  	// output: hello true
    29  }
    30  
    31  // This example demonstrates arguments that have default values
    32  func Example_defaultValues() {
    33  	// These are the args you would pass in on the command line
    34  	os.Args = split("./example")
    35  
    36  	var args struct {
    37  		Foo string `default:"abc"`
    38  	}
    39  	MustParse(&args)
    40  	fmt.Println(args.Foo)
    41  	// output: abc
    42  }
    43  
    44  // This example demonstrates arguments that are required
    45  func Example_requiredArguments() {
    46  	// These are the args you would pass in on the command line
    47  	os.Args = split("./example --foo=abc --bar")
    48  
    49  	var args struct {
    50  		Foo string `arg:"required"`
    51  		Bar bool
    52  	}
    53  	MustParse(&args)
    54  	fmt.Println(args.Foo, args.Bar)
    55  	// output: abc true
    56  }
    57  
    58  // This example demonstrates positional arguments
    59  func Example_positionalArguments() {
    60  	// These are the args you would pass in on the command line
    61  	os.Args = split("./example in out1 out2 out3")
    62  
    63  	var args struct {
    64  		Input  string   `arg:"positional"`
    65  		Output []string `arg:"positional"`
    66  	}
    67  	MustParse(&args)
    68  	fmt.Println("In:", args.Input)
    69  	fmt.Println("Out:", args.Output)
    70  	// output:
    71  	// In: in
    72  	// Out: [out1 out2 out3]
    73  }
    74  
    75  // This example demonstrates arguments that have multiple values
    76  func Example_multipleValues() {
    77  	// The args you would pass in on the command line
    78  	os.Args = split("./example --database localhost --ids 1 2 3")
    79  
    80  	var args struct {
    81  		Database string
    82  		IDs      []int64
    83  	}
    84  	MustParse(&args)
    85  	fmt.Printf("Fetching the following IDs from %s: %v", args.Database, args.IDs)
    86  	// output: Fetching the following IDs from localhost: [1 2 3]
    87  }
    88  
    89  // This example demonstrates arguments with keys and values
    90  func Example_mappings() {
    91  	// The args you would pass in on the command line
    92  	os.Args = split("./example --userids john=123 mary=456")
    93  
    94  	var args struct {
    95  		UserIDs map[string]int
    96  	}
    97  	MustParse(&args)
    98  	fmt.Println(args.UserIDs)
    99  	// output: map[john:123 mary:456]
   100  }
   101  
   102  type commaSeparated struct {
   103  	M map[string]string
   104  }
   105  
   106  func (c *commaSeparated) UnmarshalText(b []byte) error {
   107  	c.M = make(map[string]string)
   108  	for _, part := range strings.Split(string(b), ",") {
   109  		pos := strings.Index(part, "=")
   110  		if pos == -1 {
   111  			return fmt.Errorf("error parsing %q, expected format key=value", part)
   112  		}
   113  		c.M[part[:pos]] = part[pos+1:]
   114  	}
   115  	return nil
   116  }
   117  
   118  // This example demonstrates arguments with keys and values separated by commas
   119  func Example_mappingWithCommas() {
   120  	// The args you would pass in on the command line
   121  	os.Args = split("./example --values one=two,three=four")
   122  
   123  	var args struct {
   124  		Values commaSeparated
   125  	}
   126  	MustParse(&args)
   127  	fmt.Println(args.Values.M)
   128  	// output: map[one:two three:four]
   129  }
   130  
   131  // This eample demonstrates multiple value arguments that can be mixed with
   132  // other arguments.
   133  func Example_multipleMixed() {
   134  	os.Args = split("./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3")
   135  	var args struct {
   136  		Commands  []string `arg:"-c,separate"`
   137  		Files     []string `arg:"-f,separate"`
   138  		Databases []string `arg:"positional"`
   139  	}
   140  	MustParse(&args)
   141  	fmt.Println("Commands:", args.Commands)
   142  	fmt.Println("Files:", args.Files)
   143  	fmt.Println("Databases:", args.Databases)
   144  
   145  	// output:
   146  	// Commands: [cmd1 cmd2 cmd3]
   147  	// Files: [file1 file2 file3]
   148  	// Databases: [db1 db2 db3]
   149  }
   150  
   151  // This example shows the usage string generated by go-arg
   152  func Example_helpText() {
   153  	// These are the args you would pass in on the command line
   154  	os.Args = split("./example --help")
   155  
   156  	var args struct {
   157  		Input    string   `arg:"positional,required"`
   158  		Output   []string `arg:"positional"`
   159  		Verbose  bool     `arg:"-v" help:"verbosity level"`
   160  		Dataset  string   `help:"dataset to use"`
   161  		Optimize int      `arg:"-O,--optim" help:"optimization level"`
   162  	}
   163  
   164  	// This is only necessary when running inside golang's runnable example harness
   165  	osExit = func(int) {}
   166  	stdout = os.Stdout
   167  
   168  	MustParse(&args)
   169  
   170  	// output:
   171  	// Usage: example [--verbose] [--dataset DATASET] [--optim OPTIM] INPUT [OUTPUT [OUTPUT ...]]
   172  	//
   173  	// Positional arguments:
   174  	//   INPUT
   175  	//   OUTPUT
   176  	//
   177  	// Options:
   178  	//   --verbose, -v          verbosity level
   179  	//   --dataset DATASET      dataset to use
   180  	//   --optim OPTIM, -O OPTIM
   181  	//                          optimization level
   182  	//   --help, -h             display this help and exit
   183  }
   184  
   185  // This example shows the usage string generated by go-arg with customized placeholders
   186  func Example_helpPlaceholder() {
   187  	// These are the args you would pass in on the command line
   188  	os.Args = split("./example --help")
   189  
   190  	var args struct {
   191  		Input    string   `arg:"positional,required" placeholder:"SRC"`
   192  		Output   []string `arg:"positional" placeholder:"DST"`
   193  		Optimize int      `arg:"-O" help:"optimization level" placeholder:"LEVEL"`
   194  		MaxJobs  int      `arg:"-j" help:"maximum number of simultaneous jobs" placeholder:"N"`
   195  	}
   196  
   197  	// This is only necessary when running inside golang's runnable example harness
   198  	osExit = func(int) {}
   199  	stdout = os.Stdout
   200  
   201  	MustParse(&args)
   202  
   203  	// output:
   204  
   205  	// Usage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]]
   206  
   207  	// Positional arguments:
   208  	//   SRC
   209  	//   DST
   210  
   211  	// Options:
   212  	//   --optimize LEVEL, -O LEVEL
   213  	//                          optimization level
   214  	//   --maxjobs N, -j N      maximum number of simultaneous jobs
   215  	//   --help, -h             display this help and exit
   216  }
   217  
   218  // This example shows the usage string generated by go-arg when using subcommands
   219  func Example_helpTextWithSubcommand() {
   220  	// These are the args you would pass in on the command line
   221  	os.Args = split("./example --help")
   222  
   223  	type getCmd struct {
   224  		Item string `arg:"positional" help:"item to fetch"`
   225  	}
   226  
   227  	type listCmd struct {
   228  		Format string `help:"output format"`
   229  		Limit  int
   230  	}
   231  
   232  	var args struct {
   233  		Verbose bool
   234  		Get     *getCmd  `arg:"subcommand" help:"fetch an item and print it"`
   235  		List    *listCmd `arg:"subcommand" help:"list available items"`
   236  	}
   237  
   238  	// This is only necessary when running inside golang's runnable example harness
   239  	osExit = func(int) {}
   240  	stdout = os.Stdout
   241  
   242  	MustParse(&args)
   243  
   244  	// output:
   245  	// Usage: example [--verbose] <command> [<args>]
   246  	//
   247  	// Options:
   248  	//   --verbose
   249  	//   --help, -h             display this help and exit
   250  	//
   251  	// Commands:
   252  	//   get                    fetch an item and print it
   253  	//   list                   list available items
   254  }
   255  
   256  // This example shows the usage string generated by go-arg when using subcommands
   257  func Example_helpTextWhenUsingSubcommand() {
   258  	// These are the args you would pass in on the command line
   259  	os.Args = split("./example get --help")
   260  
   261  	type getCmd struct {
   262  		Item string `arg:"positional,required" help:"item to fetch"`
   263  	}
   264  
   265  	type listCmd struct {
   266  		Format string `help:"output format"`
   267  		Limit  int
   268  	}
   269  
   270  	var args struct {
   271  		Verbose bool
   272  		Get     *getCmd  `arg:"subcommand" help:"fetch an item and print it"`
   273  		List    *listCmd `arg:"subcommand" help:"list available items"`
   274  	}
   275  
   276  	// This is only necessary when running inside golang's runnable example harness
   277  	osExit = func(int) {}
   278  	stdout = os.Stdout
   279  
   280  	MustParse(&args)
   281  
   282  	// output:
   283  	// Usage: example get ITEM
   284  	//
   285  	// Positional arguments:
   286  	//   ITEM                   item to fetch
   287  	//
   288  	// Global options:
   289  	//   --verbose
   290  	//   --help, -h             display this help and exit
   291  }
   292  
   293  // This example shows how to print help for an explicit subcommand
   294  func Example_writeHelpForSubcommand() {
   295  	// These are the args you would pass in on the command line
   296  	os.Args = split("./example get --help")
   297  
   298  	type getCmd struct {
   299  		Item string `arg:"positional" help:"item to fetch"`
   300  	}
   301  
   302  	type listCmd struct {
   303  		Format string `help:"output format"`
   304  		Limit  int
   305  	}
   306  
   307  	var args struct {
   308  		Verbose bool
   309  		Get     *getCmd  `arg:"subcommand" help:"fetch an item and print it"`
   310  		List    *listCmd `arg:"subcommand" help:"list available items"`
   311  	}
   312  
   313  	// This is only necessary when running inside golang's runnable example harness
   314  	osExit = func(int) {}
   315  	stdout = os.Stdout
   316  
   317  	p, err := NewParser(Config{}, &args)
   318  	if err != nil {
   319  		fmt.Println(err)
   320  		os.Exit(1)
   321  	}
   322  
   323  	err = p.WriteHelpForSubcommand(os.Stdout, "list")
   324  	if err != nil {
   325  		fmt.Println(err)
   326  		os.Exit(1)
   327  	}
   328  
   329  	// output:
   330  	// Usage: example list [--format FORMAT] [--limit LIMIT]
   331  	//
   332  	// Options:
   333  	//   --format FORMAT        output format
   334  	//   --limit LIMIT
   335  	//
   336  	// Global options:
   337  	//   --verbose
   338  	//   --help, -h             display this help and exit
   339  }
   340  
   341  // This example shows how to print help for a subcommand that is nested several levels deep
   342  func Example_writeHelpForSubcommandNested() {
   343  	// These are the args you would pass in on the command line
   344  	os.Args = split("./example get --help")
   345  
   346  	type mostNestedCmd struct {
   347  		Item string
   348  	}
   349  
   350  	type nestedCmd struct {
   351  		MostNested *mostNestedCmd `arg:"subcommand"`
   352  	}
   353  
   354  	type topLevelCmd struct {
   355  		Nested *nestedCmd `arg:"subcommand"`
   356  	}
   357  
   358  	var args struct {
   359  		TopLevel *topLevelCmd `arg:"subcommand"`
   360  	}
   361  
   362  	// This is only necessary when running inside golang's runnable example harness
   363  	osExit = func(int) {}
   364  	stdout = os.Stdout
   365  
   366  	p, err := NewParser(Config{}, &args)
   367  	if err != nil {
   368  		fmt.Println(err)
   369  		os.Exit(1)
   370  	}
   371  
   372  	err = p.WriteHelpForSubcommand(os.Stdout, "toplevel", "nested", "mostnested")
   373  	if err != nil {
   374  		fmt.Println(err)
   375  		os.Exit(1)
   376  	}
   377  
   378  	// output:
   379  	// Usage: example toplevel nested mostnested [--item ITEM]
   380  	//
   381  	// Options:
   382  	//   --item ITEM
   383  	//   --help, -h             display this help and exit
   384  }
   385  
   386  // This example shows the error string generated by go-arg when an invalid option is provided
   387  func Example_errorText() {
   388  	// These are the args you would pass in on the command line
   389  	os.Args = split("./example --optimize INVALID")
   390  
   391  	var args struct {
   392  		Input    string   `arg:"positional,required"`
   393  		Output   []string `arg:"positional"`
   394  		Verbose  bool     `arg:"-v" help:"verbosity level"`
   395  		Dataset  string   `help:"dataset to use"`
   396  		Optimize int      `arg:"-O,help:optimization level"`
   397  	}
   398  
   399  	// This is only necessary when running inside golang's runnable example harness
   400  	osExit = func(int) {}
   401  	stderr = os.Stdout
   402  
   403  	MustParse(&args)
   404  
   405  	// output:
   406  	// Usage: example [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] INPUT [OUTPUT [OUTPUT ...]]
   407  	// error: error processing --optimize: strconv.ParseInt: parsing "INVALID": invalid syntax
   408  }
   409  
   410  // This example shows the error string generated by go-arg when an invalid option is provided
   411  func Example_errorTextForSubcommand() {
   412  	// These are the args you would pass in on the command line
   413  	os.Args = split("./example get --count INVALID")
   414  
   415  	type getCmd struct {
   416  		Count int
   417  	}
   418  
   419  	var args struct {
   420  		Get *getCmd `arg:"subcommand"`
   421  	}
   422  
   423  	// This is only necessary when running inside golang's runnable example harness
   424  	osExit = func(int) {}
   425  	stderr = os.Stdout
   426  
   427  	MustParse(&args)
   428  
   429  	// output:
   430  	// Usage: example get [--count COUNT]
   431  	// error: error processing --count: strconv.ParseInt: parsing "INVALID": invalid syntax
   432  }
   433  
   434  // This example demonstrates use of subcommands
   435  func Example_subcommand() {
   436  	// These are the args you would pass in on the command line
   437  	os.Args = split("./example commit -a -m what-this-commit-is-about")
   438  
   439  	type CheckoutCmd struct {
   440  		Branch string `arg:"positional"`
   441  		Track  bool   `arg:"-t"`
   442  	}
   443  	type CommitCmd struct {
   444  		All     bool   `arg:"-a"`
   445  		Message string `arg:"-m"`
   446  	}
   447  	type PushCmd struct {
   448  		Remote      string `arg:"positional"`
   449  		Branch      string `arg:"positional"`
   450  		SetUpstream bool   `arg:"-u"`
   451  	}
   452  	var args struct {
   453  		Checkout *CheckoutCmd `arg:"subcommand:checkout"`
   454  		Commit   *CommitCmd   `arg:"subcommand:commit"`
   455  		Push     *PushCmd     `arg:"subcommand:push"`
   456  		Quiet    bool         `arg:"-q"` // this flag is global to all subcommands
   457  	}
   458  
   459  	// This is only necessary when running inside golang's runnable example harness
   460  	osExit = func(int) {}
   461  	stderr = os.Stdout
   462  
   463  	MustParse(&args)
   464  
   465  	switch {
   466  	case args.Checkout != nil:
   467  		fmt.Printf("checkout requested for branch %s\n", args.Checkout.Branch)
   468  	case args.Commit != nil:
   469  		fmt.Printf("commit requested with message \"%s\"\n", args.Commit.Message)
   470  	case args.Push != nil:
   471  		fmt.Printf("push requested from %s to %s\n", args.Push.Branch, args.Push.Remote)
   472  	}
   473  
   474  	// output:
   475  	// commit requested with message "what-this-commit-is-about"
   476  }
   477  
   478  func Example_allSupportedTypes() {
   479  	// These are the args you would pass in on the command line
   480  	os.Args = []string{}
   481  
   482  	var args struct {
   483  		Bool     bool
   484  		Byte     byte
   485  		Rune     rune
   486  		Int      int
   487  		Int8     int8
   488  		Int16    int16
   489  		Int32    int32
   490  		Int64    int64
   491  		Float32  float32
   492  		Float64  float64
   493  		String   string
   494  		Duration time.Duration
   495  		URL      url.URL
   496  		Email    mail.Address
   497  		MAC      net.HardwareAddr
   498  	}
   499  
   500  	// go-arg supports each of the types above, as well as pointers to any of
   501  	// the above and slices of any of the above. It also supports any types that
   502  	// implements encoding.TextUnmarshaler.
   503  
   504  	MustParse(&args)
   505  
   506  	// output:
   507  }