{"id":13410482,"url":"https://github.com/alexflint/go-arg","last_synced_at":"2025-05-14T22:05:25.155Z","repository":{"id":1957824,"uuid":"45324348","full_name":"alexflint/go-arg","owner":"alexflint","description":"Struct-based argument parsing in Go","archived":false,"fork":false,"pushed_at":"2025-03-07T22:08:54.000Z","size":511,"stargazers_count":2140,"open_issues_count":31,"forks_count":103,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-05-14T22:03:45.989Z","etag":null,"topics":["argument-parsing","golang"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/alexflint/go-arg","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexflint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["alexflint"]}},"created_at":"2015-11-01T01:30:06.000Z","updated_at":"2025-05-11T16:50:11.000Z","dependencies_parsed_at":"2024-01-09T09:05:58.488Z","dependency_job_id":"2c59addd-87fa-4050-8d9c-d9a0dd9e856e","html_url":"https://github.com/alexflint/go-arg","commit_stats":{"total_commits":259,"total_committers":28,"mean_commits":9.25,"dds":0.2625482625482626,"last_synced_commit":"dfca71d1594a749ef5e2203e84cfb5a1b8e9387b"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexflint%2Fgo-arg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexflint%2Fgo-arg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexflint%2Fgo-arg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexflint%2Fgo-arg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexflint","download_url":"https://codeload.github.com/alexflint/go-arg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235687,"owners_count":22036962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argument-parsing","golang"],"created_at":"2024-07-30T20:01:07.235Z","updated_at":"2025-05-14T22:05:25.088Z","avatar_url":"https://github.com/alexflint.png","language":"Go","funding_links":["https://github.com/sponsors/alexflint"],"categories":["HarmonyOS","开源类库","Command Line","Open source library","Go","Build Automation","命令行工具### 标准 CLI`用于创建一个标准命令行应用程序的库`","命令行","\u003cspan id=\"命令行-command-line\"\u003e命令行 Command Line\u003c/span\u003e","[Go](https://go.dev/)","命令行工具"],"sub_categories":["Windows Manager","命令行","Standard CLI","Command Line","标准CLI","Useful awesome list for Dotnet cli","标准 CLI"],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"./.github/banner.jpg\" alt=\"go-arg\" height=\"250px\"\u003e\n  \u003cbr\u003e\n  go-arg\n  \u003c/br\u003e\n\u003c/h1\u003e\n\u003ch4 align=\"center\"\u003eStruct-based argument parsing for Go\u003c/h4\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://sourcegraph.com/github.com/alexflint/go-arg?badge\"\u003e\u003cimg src=\"https://sourcegraph.com/github.com/alexflint/go-arg/-/badge.svg\" alt=\"Sourcegraph\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/alexflint/go-arg\"\u003e\u003cimg src=\"https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat-square\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/alexflint/go-arg/actions\"\u003e\u003cimg src=\"https://github.com/alexflint/go-arg/workflows/Go/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/alexflint/go-arg\"\u003e\u003cimg src=\"https://codecov.io/gh/alexflint/go-arg/branch/master/graph/badge.svg\" alt=\"Coverage Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/alexflint/go-arg\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/alexflint/go-arg\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\nDeclare command line arguments for your program by defining a struct.\n\n```go\nvar args struct {\n\tFoo string\n\tBar bool\n}\narg.MustParse(\u0026args)\nfmt.Println(args.Foo, args.Bar)\n```\n\n```shell\n$ ./example --foo=hello --bar\nhello true\n```\n\n### Installation\n\n```shell\ngo get github.com/alexflint/go-arg\n```\n\n### Required arguments\n\n```go\nvar args struct {\n\tID      int `arg:\"required\"`\n\tTimeout time.Duration\n}\narg.MustParse(\u0026args)\n```\n\n```shell\n$ ./example\nUsage: example --id ID [--timeout TIMEOUT]\nerror: --id is required\n```\n\n### Positional arguments\n\n```go\nvar args struct {\n\tInput   string   `arg:\"positional\"`\n\tOutput  []string `arg:\"positional\"`\n}\narg.MustParse(\u0026args)\nfmt.Println(\"Input:\", args.Input)\nfmt.Println(\"Output:\", args.Output)\n```\n\n```shell\n$ ./example src.txt x.out y.out z.out\nInput: src.txt\nOutput: [x.out y.out z.out]\n```\n\n### Environment variables\n\n```go\nvar args struct {\n\tWorkers int `arg:\"env\"`\n}\narg.MustParse(\u0026args)\nfmt.Println(\"Workers:\", args.Workers)\n```\n\n```shell\n$ WORKERS=4 ./example\nWorkers: 4\n```\n\n```shell\n$ WORKERS=4 ./example --workers=6\nWorkers: 6\n```\n\nYou can also override the name of the environment variable:\n\n```go\nvar args struct {\n\tWorkers int `arg:\"env:NUM_WORKERS\"`\n}\narg.MustParse(\u0026args)\nfmt.Println(\"Workers:\", args.Workers)\n```\n\n```shell\n$ NUM_WORKERS=4 ./example\nWorkers: 4\n```\n\nYou can provide multiple values in environment variables using commas:\n\n```go\nvar args struct {\n    Workers []int `arg:\"env\"`\n}\narg.MustParse(\u0026args)\nfmt.Println(\"Workers:\", args.Workers)\n```\n\n```shell\n$ WORKERS='1,99' ./example\nWorkers: [1 99]\n```\n\nCommand line arguments take precedence over environment variables:\n\n```go\nvar args struct {\n\tWorkers int `arg:\"--count,env:NUM_WORKERS\"`\n}\narg.MustParse(\u0026args)\nfmt.Println(\"Workers:\", args.Workers)\n```\n\n```shell\n$ NUM_WORKERS=6 ./example\nWorkers: 6\n$ NUM_WORKERS=6 ./example --count 4\nWorkers: 4\n```\n\nConfiguring a global environment variable name prefix is also possible:\n\n```go\nvar args struct {\n\tWorkers int `arg:\"--count,env:NUM_WORKERS\"`\n}\n\np, err := arg.NewParser(arg.Config{\n    EnvPrefix: \"MYAPP_\",\n}, \u0026args)\n\np.MustParse(os.Args[1:])\nfmt.Println(\"Workers:\", args.Workers)\n```\n\n```shell\n$ MYAPP_NUM_WORKERS=6 ./example\nWorkers: 6\n```\n\n### Usage strings\n\n```go\nvar args struct {\n\tInput    string   `arg:\"positional\"`\n\tOutput   []string `arg:\"positional\"`\n\tVerbose  bool     `arg:\"-v,--verbose\" help:\"verbosity level\"`\n\tDataset  string   `help:\"dataset to use\"`\n\tOptimize int      `arg:\"-O\" help:\"optimization level\"`\n}\narg.MustParse(\u0026args)\n```\n\n```shell\n$ ./example -h\nUsage: [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] [--help] INPUT [OUTPUT [OUTPUT ...]]\n\nPositional arguments:\n  INPUT\n  OUTPUT\n\nOptions:\n  --verbose, -v            verbosity level\n  --dataset DATASET        dataset to use\n  --optimize OPTIMIZE, -O OPTIMIZE\n                           optimization level\n  --help, -h               print this help message\n```\n\n### Default values\n\n```go\nvar args struct {\n\tFoo string `default:\"abc\"`\n\tBar bool\n}\narg.MustParse(\u0026args)\n```\n\nCommand line arguments take precedence over environment variables, which take precedence over default values. This means that we check whether a certain option was provided on the command line, then if not, we check for an environment variable (only if an `env` tag was provided), then if none is found, we check for a `default` tag containing a default value.\n\n```go\nvar args struct {\n    Test  string `arg:\"-t,env:TEST\" default:\"something\"`\n}\narg.MustParse(\u0026args)\n```\n\n#### Ignoring environment variables and/or default values\n\n```go\nvar args struct {\n    Test  string `arg:\"-t,env:TEST\" default:\"something\"`\n}\n\np, err := arg.NewParser(arg.Config{\n    IgnoreEnv: true,\n    IgnoreDefault: true,\n}, \u0026args)\n\nerr = p.Parse(os.Args[1:])\n```\n\n### Arguments with multiple values\n\n```go\nvar args struct {\n\tDatabase string\n\tIDs      []int64\n}\narg.MustParse(\u0026args)\nfmt.Printf(\"Fetching the following IDs from %s: %q\", args.Database, args.IDs)\n```\n\n```shell\n./example -database foo -ids 1 2 3\nFetching the following IDs from foo: [1 2 3]\n```\n\n### Arguments that can be specified multiple times, mixed with positionals\n\n```go\nvar args struct {\n    Commands  []string `arg:\"-c,separate\"`\n    Files     []string `arg:\"-f,separate\"`\n    Databases []string `arg:\"positional\"`\n}\narg.MustParse(\u0026args)\n```\n\n```shell\n./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3\nCommands: [cmd1 cmd2 cmd3]\nFiles [file1 file2 file3]\nDatabases [db1 db2 db3]\n```\n\n### Arguments with keys and values\n\n```go\nvar args struct {\n\tUserIDs map[string]int\n}\narg.MustParse(\u0026args)\nfmt.Println(args.UserIDs)\n```\n\n```shell\n./example --userids john=123 mary=456\nmap[john:123 mary:456]\n```\n\n### Version strings\n\n```go\ntype args struct {\n\t...\n}\n\nfunc (args) Version() string {\n\treturn \"someprogram 4.3.0\"\n}\n\nfunc main() {\n\tvar args args\n\targ.MustParse(\u0026args)\n}\n```\n\n```shell\n$ ./example --version\nsomeprogram 4.3.0\n```\n\n\u003e **Note**\n\u003e If a `--version` flag is defined in `args` or any subcommand, it overrides the built-in versioning.\n\n### Custom validation\n\n```go\nvar args struct {\n\tFoo string\n\tBar string\n}\np := arg.MustParse(\u0026args)\nif args.Foo == \"\" \u0026\u0026 args.Bar == \"\" {\n\tp.Fail(\"you must provide either --foo or --bar\")\n}\n```\n\n```shell\n./example\nUsage: samples [--foo FOO] [--bar BAR]\nerror: you must provide either --foo or --bar\n```\n\n### Overriding option names\n\n```go\nvar args struct {\n\tShort        string `arg:\"-s\"`\n\tLong         string `arg:\"--custom-long-option\"`\n\tShortAndLong string `arg:\"-x,--my-option\"`\n\tOnlyShort    string `arg:\"-o,--\"`\n}\narg.MustParse(\u0026args)\n```\n\n```shell\n$ ./example --help\nUsage: example [-o ONLYSHORT] [--short SHORT] [--custom-long-option CUSTOM-LONG-OPTION] [--my-option MY-OPTION]\n\nOptions:\n  --short SHORT, -s SHORT\n  --custom-long-option CUSTOM-LONG-OPTION\n  --my-option MY-OPTION, -x MY-OPTION\n  -o ONLYSHORT\n  --help, -h             display this help and exit\n```\n\n### Embedded structs\n\nThe fields of embedded structs are treated just like regular fields:\n\n```go\ntype DatabaseOptions struct {\n\tHost     string\n\tUsername string\n\tPassword string\n}\n\ntype LogOptions struct {\n\tLogFile string\n\tVerbose bool\n}\n\nfunc main() {\n\tvar args struct {\n\t\tDatabaseOptions\n\t\tLogOptions\n\t}\n\targ.MustParse(\u0026args)\n}\n```\n\nAs usual, any field tagged with `arg:\"-\"` is ignored.\n\n### Supported types\n\nThe following types may be used as arguments:\n- built-in integer types: `int, int8, int16, int32, int64, byte, rune`\n- built-in floating point types: `float32, float64`\n- strings\n- booleans\n- URLs represented as `url.URL`\n- time durations represented as `time.Duration`\n- email addresses represented as `mail.Address`\n- MAC addresses represented as `net.HardwareAddr`\n- pointers to any of the above\n- slices of any of the above\n- maps using any of the above as keys and values\n- any type that implements `encoding.TextUnmarshaler`\n\n### Custom parsing\n\nImplement `encoding.TextUnmarshaler` to define your own parsing logic.\n\n```go\n// Accepts command line arguments of the form \"head.tail\"\ntype NameDotName struct {\n\tHead, Tail string\n}\n\nfunc (n *NameDotName) UnmarshalText(b []byte) error {\n\ts := string(b)\n\tpos := strings.Index(s, \".\")\n\tif pos == -1 {\n\t\treturn fmt.Errorf(\"missing period in %s\", s)\n\t}\n\tn.Head = s[:pos]\n\tn.Tail = s[pos+1:]\n\treturn nil\n}\n\nfunc main() {\n\tvar args struct {\n\t\tName NameDotName\n\t}\n\targ.MustParse(\u0026args)\n\tfmt.Printf(\"%#v\\n\", args.Name)\n}\n```\n\n```shell\n$ ./example --name=foo.bar\nmain.NameDotName{Head:\"foo\", Tail:\"bar\"}\n\n$ ./example --name=oops\nUsage: example [--name NAME]\nerror: error processing --name: missing period in \"oops\"\n```\n\n### Custom parsing with default values\n\nImplement `encoding.TextMarshaler` to define your own default value strings:\n\n```go\n// Accepts command line arguments of the form \"head.tail\"\ntype NameDotName struct {\n\tHead, Tail string\n}\n\nfunc (n *NameDotName) UnmarshalText(b []byte) error {\n\t// same as previous example\n}\n\n// this is only needed if you want to display a default value in the usage string\nfunc (n *NameDotName) MarshalText() ([]byte, error) {\n\treturn []byte(fmt.Sprintf(\"%s.%s\", n.Head, n.Tail)), nil\n}\n\nfunc main() {\n\tvar args struct {\n\t\tName NameDotName `default:\"file.txt\"`\n\t}\n\targ.MustParse(\u0026args)\n\tfmt.Printf(\"%#v\\n\", args.Name)\n}\n```\n\n```shell\n$ ./example --help\nUsage: test [--name NAME]\n\nOptions:\n  --name NAME [default: file.txt]\n  --help, -h             display this help and exit\n\n$ ./example\nmain.NameDotName{Head:\"file\", Tail:\"txt\"}\n```\n\n### Custom placeholders\n\nUse the `placeholder` tag to control which placeholder text is used in the usage text.\n\n```go\nvar args struct {\n\tInput    string   `arg:\"positional\" placeholder:\"SRC\"`\n\tOutput   []string `arg:\"positional\" placeholder:\"DST\"`\n\tOptimize int      `arg:\"-O\" help:\"optimization level\" placeholder:\"LEVEL\"`\n\tMaxJobs  int      `arg:\"-j\" help:\"maximum number of simultaneous jobs\" placeholder:\"N\"`\n}\narg.MustParse(\u0026args)\n```\n\n```shell\n$ ./example -h\nUsage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]]\n\nPositional arguments:\n  SRC\n  DST\n\nOptions:\n  --optimize LEVEL, -O LEVEL\n                         optimization level\n  --maxjobs N, -j N      maximum number of simultaneous jobs\n  --help, -h             display this help and exit\n```\n\n### Description strings\n\nA descriptive message can be added at the top of the help text by implementing\na `Description` function that returns a string.\n\n```go\ntype args struct {\n\tFoo string\n}\n\nfunc (args) Description() string {\n\treturn \"this program does this and that\"\n}\n\nfunc main() {\n\tvar args args\n\targ.MustParse(\u0026args)\n}\n```\n\n```shell\n$ ./example -h\nthis program does this and that\nUsage: example [--foo FOO]\n\nOptions:\n  --foo FOO\n  --help, -h             display this help and exit\n```\n\nSimilarly an epilogue can be added at the end of the help text by implementing\nthe `Epilogue` function.\n\n```go\ntype args struct {\n\tFoo string\n}\n\nfunc (args) Epilogue() string {\n\treturn \"For more information visit github.com/alexflint/go-arg\"\n}\n\nfunc main() {\n\tvar args args\n\targ.MustParse(\u0026args)\n}\n```\n\n```shell\n$ ./example -h\nUsage: example [--foo FOO]\n\nOptions:\n  --foo FOO\n  --help, -h             display this help and exit\n\nFor more information visit github.com/alexflint/go-arg\n```\n\n### Subcommands\n\nSubcommands are commonly used in tools that wish to group multiple functions into a single program. An example is the `git` tool:\n```shell\n$ git checkout [arguments specific to checking out code]\n$ git commit [arguments specific to committing]\n$ git push [arguments specific to pushing]\n```\n\nThe strings \"checkout\", \"commit\", and \"push\" are different from simple positional arguments because the options available to the user change depending on which subcommand they choose.\n\nThis can be implemented with `go-arg` as follows:\n\n```go\ntype CheckoutCmd struct {\n\tBranch string `arg:\"positional\"`\n\tTrack  bool   `arg:\"-t\"`\n}\ntype CommitCmd struct {\n\tAll     bool   `arg:\"-a\"`\n\tMessage string `arg:\"-m\"`\n}\ntype PushCmd struct {\n\tRemote      string `arg:\"positional\"`\n\tBranch      string `arg:\"positional\"`\n\tSetUpstream bool   `arg:\"-u\"`\n}\nvar args struct {\n\tCheckout *CheckoutCmd `arg:\"subcommand:checkout\"`\n\tCommit   *CommitCmd   `arg:\"subcommand:commit\"`\n\tPush     *PushCmd     `arg:\"subcommand:push\"`\n\tQuiet    bool         `arg:\"-q\"` // this flag is global to all subcommands\n}\n\narg.MustParse(\u0026args)\n\nswitch {\ncase args.Checkout != nil:\n\tfmt.Printf(\"checkout requested for branch %s\\n\", args.Checkout.Branch)\ncase args.Commit != nil:\n\tfmt.Printf(\"commit requested with message \\\"%s\\\"\\n\", args.Commit.Message)\ncase args.Push != nil:\n\tfmt.Printf(\"push requested from %s to %s\\n\", args.Push.Branch, args.Push.Remote)\n}\n```\n\nSome additional rules apply when working with subcommands:\n* The `subcommand` tag can only be used with fields that are pointers to structs\n* Any struct that contains a subcommand must not contain any positionals\n\nThis package allows to have a program that accepts subcommands, but also does something else\nwhen no subcommands are specified.\nIf on the other hand you want the program to terminate when no subcommands are specified,\nthe recommended way is:\n\n```go\np := arg.MustParse(\u0026args)\nif p.Subcommand() == nil {\n    p.Fail(\"missing subcommand\")\n}\n```\n\n### Custom handling of --help and --version\n\nThe following reproduces the internal logic of `MustParse` for the simple case where\nyou are not using subcommands or --version. This allows you to respond\nprogramatically to --help, and to any errors that come up.\n\n```go\nvar args struct {\n\tSomething string\n}\n\np, err := arg.NewParser(arg.Config{}, \u0026args)\nif err != nil {\n\tlog.Fatalf(\"there was an error in the definition of the Go struct: %v\", err)\n}\n\nerr = p.Parse(os.Args[1:])\nswitch {\ncase err == arg.ErrHelp:  // indicates that user wrote \"--help\" on command line\n\tp.WriteHelp(os.Stdout)\n\tos.Exit(0)\ncase err != nil:\n\tfmt.Printf(\"error: %v\\n\", err)\n\tp.WriteUsage(os.Stdout)\n\tos.Exit(1)\n}\n```\n\n```shell\n$ go run ./example --help\nUsage: ./example --something SOMETHING\n\nOptions:\n  --something SOMETHING\n  --help, -h             display this help and exit\n\n$ ./example --wrong\nerror: unknown argument --wrong\nUsage: ./example --something SOMETHING\n\n$ ./example\nerror: --something is required\nUsage: ./example --something SOMETHING\n```\n\nTo also handle --version programatically, use the following:\n\n```go\ntype args struct {\n\tSomething string\n}\n\nfunc (args) Version() string {\n\treturn \"1.2.3\"\n}\n\nfunc main() {\n\tvar args args\n\tp, err := arg.NewParser(arg.Config{}, \u0026args)\n\tif err != nil {\n\t\tlog.Fatalf(\"there was an error in the definition of the Go struct: %v\", err)\n\t}\n\n\terr = p.Parse(os.Args[1:])\n\tswitch {\n\tcase err == arg.ErrHelp: // found \"--help\" on command line\n\t\tp.WriteHelp(os.Stdout)\n\t\tos.Exit(0)\n\tcase err == arg.ErrVersion: // found \"--version\" on command line\n\t\tfmt.Println(args.Version())\n\t\tos.Exit(0)\n\tcase err != nil:\n\t\tfmt.Printf(\"error: %v\\n\", err)\n\t\tp.WriteUsage(os.Stdout)\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Printf(\"got %q\\n\", args.Something)\n}\n```\n\n```shell\n$ ./example --version\n1.2.3\n\n$ go run ./example --help\n1.2.3\nUsage: example --something SOMETHING\n\nOptions:\n  --something SOMETHING\n  --help, -h             display this help and exit\n\n$ ./example --wrong\n1.2.3\nerror: unknown argument --wrong\nUsage: example --something SOMETHING\n\n$ ./example\nerror: --something is required\nUsage: example --something SOMETHING\n```\n\nTo generate subcommand-specific help messages, use the following most general version\n(this also works in absence of subcommands but is a bit more complex):\n\n```go\ntype fetchCmd struct {\n\tCount int\n}\n\ntype args struct {\n\tSomething string\n\tFetch     *fetchCmd `arg:\"subcommand\"`\n}\n\nfunc (args) Version() string {\n\treturn \"1.2.3\"\n}\n\nfunc main() {\n\tvar args args\n\tp, err := arg.NewParser(arg.Config{}, \u0026args)\n\tif err != nil {\n\t\tlog.Fatalf(\"there was an error in the definition of the Go struct: %v\", err)\n\t}\n\n\terr = p.Parse(os.Args[1:])\n\tswitch {\n\tcase err == arg.ErrHelp: // found \"--help\" on command line\n\t\tp.WriteHelpForSubcommand(os.Stdout, p.SubcommandNames()...)\n\t\tos.Exit(0)\n\tcase err == arg.ErrVersion: // found \"--version\" on command line\n\t\tfmt.Println(args.Version())\n\t\tos.Exit(0)\n\tcase err != nil:\n\t\tfmt.Printf(\"error: %v\\n\", err)\n\t\tp.WriteUsageForSubcommand(os.Stdout, p.SubcommandNames()...)\n\t\tos.Exit(1)\n\t}\n}\n```\n\n```shell\n$ ./example --version\n1.2.3\n\n$ ./example --help\n1.2.3\nUsage: example [--something SOMETHING] \u003ccommand\u003e [\u003cargs\u003e]\n\nOptions:\n  --something SOMETHING\n  --help, -h             display this help and exit\n  --version              display version and exit\n\nCommands:\n  fetch\n\n$ ./example fetch --help\n1.2.3\nUsage: example fetch [--count COUNT]\n\nOptions:\n  --count COUNT\n\nGlobal options:\n  --something SOMETHING\n  --help, -h             display this help and exit\n  --version              display version and exit\n```\n\n### API Documentation\n\nhttps://pkg.go.dev/github.com/alexflint/go-arg\n\n### Rationale\n\nThere are many command line argument parsing libraries for Go, including one in the standard library, so why build another?\n\nThe `flag` library that ships in the standard library seems awkward to me. Positional arguments must precede options, so `./prog x --foo=1` does what you expect but `./prog --foo=1 x` does not. It also does not allow arguments to have both long (`--foo`) and short (`-f`) forms.\n\nMany third-party argument parsing libraries are great for writing sophisticated command line interfaces, but feel to me like overkill for a simple script with a few flags.\n\nThe idea behind `go-arg` is that Go already has an excellent way to describe data structures using structs, so there is no need to develop additional levels of abstraction. Instead of one API to specify which arguments your program accepts, and then another API to get the values of those arguments, `go-arg` replaces both with a single struct.\n\n### Backward compatibility notes\n\nEarlier versions of this library required the help text to be part of the `arg` tag. This is still supported but is now deprecated. Instead, you should use a separate `help` tag, described above, which makes it possible to include commas inside help text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexflint%2Fgo-arg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexflint%2Fgo-arg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexflint%2Fgo-arg/lists"}