func main() { parser := args.NewParser(args.Name("http-client"), args.Desc("Example http client client")) parser.AddOption("--verbose").Alias("-v").Count(). Help("Be verbose") parser.AddOption("--endpoint").Default("http://localhost:1234").Env("API_ENDPOINT"). Help("The HTTP endpoint our client will talk too") parser.AddCommand("super-chickens", func(subParser *args.ArgParser, data interface{}) int { subParser.AddCommand("create", createChickens) subParser.AddCommand("list", listChickens) subParser.AddCommand("delete", deleteChickens) // Apply our super metadata =) shared := data.(*SharedStruct) shared.Metadata = "super" // Run the sub-commands retCode, err := subParser.ParseAndRun(nil, data) if err != nil { fmt.Println(err.Error()) return 1 } return retCode }) // Add our non super chicken actions parser.AddCommand("create", createChickens) parser.AddCommand("list", listChickens) parser.AddCommand("delete", deleteChickens) // Parse the command line opts, err := parser.ParseArgs(nil) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } // Build our url from what the user passed in parts, err := url.Parse(opts.String("endpoint")) if err != nil { fmt.Fprint(os.Stderr, "url endpoint '%s' is invalid", opts.String("endpoint"), err.Error()) os.Exit(1) } // This is a shows how you can pass in arbitrary struct // data to your sub-commands allows you to share data and resources // with sub-commands with out resorting to global variables super := &SharedStruct{Metadata: "", Url: parts} // Run the command chosen by the user retCode, err := parser.RunCommand(super) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } os.Exit(retCode) }
func main() { var conf Config // Create the parser with program name 'example' // and environment variables prefixed with APP_ parser := args.NewParser(args.Name("demo"), args.EnvPrefix("APP_"), args.Desc("This is a demo app to showcase some features of args")) // Store Integers directly into a struct with a default value parser.AddOption("--power-level").Alias("-p").StoreInt(&conf.PowerLevel). Env("POWER_LEVEL").Default("10000").Help("set our power level") // Command line options can begin with -name, --name or even ++name // Most non word characters are supported parser.AddOption("++config-file").Alias("+c").IsString(). Default("/path/to/config").Help("path to config file") // Use the args.Env() function to define an environment variable // NOTE: Since the parser was passed args.EnvPrefix("APP_") the actual // environment variable name is 'APP_MESSAGE' parser.AddOption("--message").Alias("-m").StoreStr(&conf.Message). Env("MESSAGE").Default("over-ten-thousand").Help("send a message") // Pass a comma separated list of strings and get a []string slice parser.AddOption("--slice").Alias("-s").StoreStringSlice(&conf.StringSlice).Env("LIST"). Default("one,two,three").Help("list of messages") // Count the number of times an option is seen parser.AddOption("--verbose").Alias("-v").Count().StoreInt(&conf.Verbose).Help("be verbose") // Set bool to true if the option is present on the command line parser.AddOption("--debug").Alias("-d").IsTrue().Help("turn on Debug") // Specify the type of the arg with IsInt(), IsString(), IsBool() or IsTrue() parser.AddOption("--help").Alias("-h").IsTrue().Help("show this help message") // Add Required arguments parser.AddArgument("the-question").Required(). StoreStr(&conf.TheQuestion).Help("Before you have an answer") // Add Optional arguments parser.AddArgument("the-answer").IsInt().Default("42"). StoreInt(&conf.TheAnswer).Help("It must be 42") // 'Conf' options are not set via the command line but can be set // via a config file or an environment variable parser.AddConfig("twelve-factor").Env("TWELVE_FACTOR").Help("Demo of config options") // Define a 'database' subgroup db := parser.InGroup("database") // Add command line options to the subgroup db.AddOption("--host").Alias("-dH").StoreStr(&conf.DbHost). Default("localhost").Help("database hostname") // Add subgroup specific config. 'Conf' options are not set via the // command line but can be set via a config file or anything that calls parser.Apply() db.AddConfig("debug").IsTrue().Help("enable database debug") // 'Conf' option names are not allowed to start with a non word character like // '--' or '++' so they can not be confused with command line options db.AddConfig("database").IsString().Default("myDatabase").Help("name of database to use") // If no type is specified, defaults to 'IsString' db.AddConfig("user").Help("database user") db.AddConfig("pass").Help("database password") // Pass our own argument list, or nil to parse os.Args[] opt := parser.ParseArgsSimple(nil) // NOTE: ParseArgsSimple() is just a convenience, you can call // parser.ParseArgs(nil) directly and handle the errors // yourself if you have more complicated use case // Demo default variables in a struct fmt.Printf("Power '%d'\n", conf.PowerLevel) fmt.Printf("Message '%s'\n", conf.Message) fmt.Printf("String Slice '%s'\n", conf.StringSlice) fmt.Printf("DbHost '%s'\n", conf.DbHost) fmt.Printf("TheAnswer '%d'\n", conf.TheAnswer) fmt.Println("") // If user asked for --help or there were no options // passed and none where required if opt.NoArgs() || opt.Bool("help") { parser.PrintHelp() os.Exit(-1) } fmt.Println("") fmt.Println("==================") fmt.Println(" Direct Cast") fmt.Println("==================") // Fetch values by using the Cast functions fmt.Printf("Power '%d'\n", opt.Int("power-level")) fmt.Printf("Message '%s'\n", opt.String("message")) fmt.Printf("String Slice '%s'\n", opt.StringSlice("slice")) fmt.Printf("Verbose '%d'\n", opt.Int("verbose")) fmt.Printf("Debug '%t'\n", opt.Bool("debug")) fmt.Printf("TheAnswer '%d'\n", opt.Int("the-answer")) fmt.Printf("TheAnswer as String '%s'\n", opt.String("the-answer")) fmt.Println("") fmt.Println("==================") fmt.Println(" Database Group") fmt.Println("==================") // Fetch Group values dbAddOption := opt.Group("database") fmt.Printf("CAST DB Host '%s'\n", dbAddOption.String("host")) fmt.Printf("CAST DB Debug '%t'\n", dbAddOption.Bool("debug")) fmt.Printf("CAST DB User '%s'\n", dbAddOption.String("user")) fmt.Printf("CAST DB Pass '%s'\n", dbAddOption.String("pass")) fmt.Println("") iniFile := []byte(` power-level=20000 message=OVER-TEN-THOUSAND! slice=three,four,five,six verbose=5 debug=true [database] debug=false host=mysql.thrawn01.org user=my-username pass=my-password `) // Make configuration simple by reading arguments from an INI file opts, err := parser.FromINI(iniFile) if err != nil { fmt.Println(err.Error()) os.Exit(-1) } fmt.Println("") fmt.Println("==================") fmt.Println("From INI file") fmt.Println("==================") // Values from the config file are used only if the argument is not present // on the commandline fmt.Printf("INI Power '%d'\n", conf.PowerLevel) fmt.Printf("INI Message '%s'\n", conf.Message) fmt.Printf("INI Slice '%s'\n", conf.StringSlice) fmt.Printf("INI Verbose '%d'\n", conf.Verbose) fmt.Printf("INI Debug '%t'\n", opts.Bool("debug")) fmt.Println("") // Create an Options object from a map opts = parser.NewOptionsFromMap( map[string]interface{}{ "int": 1, "bool": true, "string": "one", "endpoints": map[string]interface{}{ "endpoint1": "host1", "endpoint2": "host2", "endpoint3": "host3", }, "deeply": map[string]interface{}{ "nested": map[string]interface{}{ "thing": "foo", }, "foo": "bar", }, }, ) // Small demo of how Group() works with options opts.String("string") // == "one" opts.Group("endpoints") // == *args.Options opts.Group("endpoints").String("endpoint1") // == "host1" opts.Group("endpoints").ToMap() // map[string]interface{} {"endpoint1": "host1", ...} opts.StringMap("endpoints") // map[string]string {"endpoint1": "host1", ...} opts.KeySlice("endpoints") // [ "endpoint1", "endpoint2", ] opts.StringSlice("endpoints") // [ "host1", "host2", "host3" ] // Leaves the door open for IntSlice(), IntMap(), etc.... }
func main() { parser := args.NewParser(args.Name("watch")) parser.AddOption("--bind").Alias("-b").Default("localhost:8080"). Help("Interface to bind the server too") parser.AddOption("--complex-example").Alias("-ce").IsBool(). Help("Run the more complex example") parser.AddOption("--config-file").Alias("-c"). Help("The Config file to load and watch our config from") // Add a connection string to the database group parser.AddOption("--connection-string").InGroup("database").Alias("-cS"). Default("mysql://username@hostname:MyDB"). Help("Connection string used to connect to the database") // Store the password in the config and not passed via the command line parser.AddConfig("password").InGroup("database").Help("database password") // Specify a config file version, when this version number is updated, the user is signaling to the application // that all edits are complete and the application can reload the config parser.AddConfig("version").IsInt().Default("0").Help("config file version") appConf, err := parser.ParseArgs(nil) if err != nil { fmt.Println(err.Error()) os.Exit(-1) } // Simple handler that prints out our config information http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { conf := appConf.GetOpts() db := conf.Group("database") payload, err := json.Marshal(map[string]string{ "bind": conf.String("bind"), "mysql": db.String("connection-string"), "password": conf.Group("database").String("password"), }) if err != nil { fmt.Println("error:", err) } w.Header().Set("Content-Type", "application/json") w.Write(payload) }) var cancelWatch args.WatchCancelFunc if appConf.Bool("complex-example") { cancelWatch = complex(parser) } else { cancelWatch = simple(parser) } // Shut down the watcher when done defer cancelWatch() // Listen and serve requests log.Printf("Listening for requests on %s", appConf.String("bind")) err = http.ListenAndServe(appConf.String("bind"), nil) if err != nil { log.Println(err) os.Exit(-1) } }
func main() { var conf Config // Create the parser parser := args.Parser(args.Name("example")) // Store Integers directly into a struct with a default value parser.Opt("--power-level", args.Alias("-p"), args.StoreInt(&conf.PowerLevel), args.Env("POWER_LEVEL"), args.Default("10000"), args.Help("set our power level")) // Options can begin with -name, --name or even ++name. Most alpha non word character are supported parser.Opt("++power", args.Alias("+p"), args.IsString(), args.Default("11,000"), args.Help("prefix demo")) // Use the args.Env() function to define an environment variable parser.Opt("--message", args.Alias("-m"), args.StoreStr(&conf.Message), args.Env("MESSAGE"), args.Default("over-ten-thousand"), args.Help("send a message")) // Pass a comma seperated list of strings and get a []string parser.Opt("--slice", args.Alias("-s"), args.StoreSlice(&conf.Slice), args.Env("LIST"), args.Default("one,two,three"), args.Help("list of messages")) // Count the number of times an argument is seen parser.Opt("--verbose", args.Alias("-v"), args.Count(), args.StoreInt(&conf.Verbose), args.Help("be verbose")) // Set bool to true if the argument is present on the command line parser.Opt("--debug", args.Alias("-d"), args.IsTrue(), args.Help("turn on Debug")) // Specify the type of the arg with IsInt(), IsString(), IsBool() or IsTrue() parser.Opt("--help", args.Alias("-h"), args.IsTrue(), args.Help("show this help message")) // Pass our own argument list, or nil to parse os.Args[] opt, err := parser.ParseArgs(nil) if err != nil { fmt.Println(err.Error()) os.Exit(-1) } // Fetch values by using the Cast functions fmt.Printf("CAST Power '%d'\n", opt.Int("power-level")) fmt.Printf("CAST Message '%s'\n", opt.String("message")) fmt.Printf("CAST Slice '%s'\n", opt.Slice("slice")) fmt.Printf("CAST Verbose '%d'\n", opt.Int("verbose")) fmt.Printf("CAST Debug '%t'\n", opt.Bool("debug")) fmt.Println("") // Values can also be stored in a struct fmt.Printf("STRUCT Power '%d'\n", conf.PowerLevel) fmt.Printf("STRUCT Message '%s'\n", conf.Message) fmt.Printf("STRUCT Slice '%s'\n", conf.Slice) fmt.Printf("STRUCT Verbose '%d'\n", conf.Verbose) fmt.Printf("STRUCT Debug '%t'\n", opt.Bool("debug")) fmt.Println("") iniFile := []byte(` power-level=20000 message=OVER-THEN-THOUSAND! slice=three,four,five,six verbose=5 debug=true `) // Make configuration simply by reading arguments from an INI file opt, err = parser.ParseIni(iniFile) if err != nil { fmt.Println(err.Error()) os.Exit(-1) } // Values from the config file are used only if the argument is not present // on the commandline fmt.Printf("INI Power '%d'\n", conf.PowerLevel) fmt.Printf("INI Message '%s'\n", conf.Message) fmt.Printf("INI Slice '%s'\n", conf.Slice) fmt.Printf("INI Verbose '%d'\n", conf.Verbose) fmt.Printf("INI Debug '%t'\n", opt.Bool("debug")) fmt.Println("") // If user asked for --help or there were no options passed if opt.NoArgs() || opt.Bool("help") { parser.PrintHelp() os.Exit(-1) } }
parser := args.NewParser(args.WrapLen(80)) parser.AddOption("--power-level").Alias("-p").Help("Specify our power level") parser.AddOption("--cat-level"). Alias("-c"). Help(`Lorem ipsum dolor sit amet, consectetur mollit anim id est laborum.`) msg := parser.GenerateHelpSection(args.IsOption) Expect(msg).To(Equal(" -p, --power-level Specify our power level" + "\n -c, --cat-level Lorem ipsum dolor sit amet, consecteturmollit anim id est" + "\n laborum.\n")) }) }) Describe("ArgParser.GenerateHelp()", func() { It("Should generate help messages given a set of rules", func() { parser := args.NewParser(args.EnvPrefix("APP_"), args.Desc("Small Description"), args.Name("dragon-ball"), args.WrapLen(80)) parser.AddOption("--environ").Default("1").Alias("-e").Env("ENV").Help("Default thing") parser.AddOption("--default").Default("0").Alias("-d").Help("Default thing") parser.AddOption("--power-level").Alias("-p").Help("Specify our power level") parser.AddOption("--cat-level").Alias("-c").Help(`Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et mollit anim id est laborum.`) msg := parser.GenerateHelp() Expect(msg).To(ContainSubstring("Usage: dragon-ball [OPTIONS]")) Expect(msg).To(ContainSubstring("-e, --environ Default thing (Default=1, Env=APP_ENV)")) Expect(msg).To(ContainSubstring("-d, --default Default thing (Default=0)")) Expect(msg).To(ContainSubstring("-p, --power-level Specify our power level")) Expect(msg).To(ContainSubstring("Small Description")) }) It("Should generate formated description if flag is set", func() { desc := `