Build a command line argument parser by defining a struct
This example is in example/simple/main.go
// define flag, default and usage in struct field's tags
type Arg struct {
// Flags(no value) are defined by bool type field
Help bool `flag:"h" default:"false" usage:"print help"`
// Arguments(with value) are defined by field of their types
// define flag, default and usage in struct field's tags
// flag, default and usage in tag are all optional
Name string `flag:"name" default:"you" usage:"your name"`
Email string `flag:"email" default:"[email protected]" usage:"your email"`
// subcommands are defined by *struct{...} field
Add *struct {
All bool `flag:"a" default:"false" usage:"Add all files"`
File string `flag:"f" usage:"file to be added"`
} `flag:"add" usage:"Add file contents to the index"`
Commit *struct{} `flag:"commit" usage:"Record changes to the repository"`
// subcommands can be nested inside of subcommands!
Push *struct {
Origin *struct{} `flag:"origin" usage:"Push to origin"`
} `flag:"push" usage:"Push to remote repository"`
}
func main() {
var arg Arg // init a empty argument struct
parser := scli.BuildParser(&arg)
parser.Parse()
fmt.Printf("%v\n", prettyPrint(arg))
}
Below are some examples of input CLI arguments and parsed values of arg
.
$ ./mygit
{
"Help": false,
"Name": "you",
"Email": "[email protected]",
"Add": null,
"Commit": null,
"Push": null
}
$ ./mygit --name canoriz
{
"Help": false,
"Name": "canoriz",
"Email": "[email protected]",
"Add": null,
"Commit": null,
"Push": null
}
$ ./mygit --name canoriz add -a -f source-code
{
"Help": false,
"Name": "canoriz",
"Email": "[email protected]",
"Add": {
"All": true,
"File": "source-code"
},
"Commit": null,
"Push": null
}
$ ./mygit --name canoriz commit
{
"Help": false,
"Name": "canoriz",
"Email": "[email protected]",
"Add": null,
"Commit": {},
"Push": null
}
$ ./mygit --name canoriz push origin
{
"Help": false,
"Name": "canoriz",
"Email": "[email protected]",
"Add": null,
"Commit": null,
"Push": {
"Origin": {}
}
}
$ ./mygit --name canoriz push
{
"Help": false,
"Name": "canoriz",
"Email": "[email protected]",
"Add": null,
"Commit": null,
"Push": {
"Origin": null
}
}
$ ./mygit --name canoriz add
error: argument "--f" is required in "./mygit add" but not provided
The usage is:
Usage: ./mygit add [OPTIONS]
Options:
-help, --help print this message
--a, --/a set [Add all files] to true / false [default: false]
--f <file to be added>
$ ./mygit --help
Usage: ./mygit [OPTIONS] [COMMAND]
Commands:
add Add file contents to the index
commit Record changes to the repository
push Push to remote repository
Options:
-help, --help print this message
--email <your email> [default: "[email protected]"]
--h, --/h set [print help] to true / false [default: false]
--name <your name> [default: "you"]
Run `./mygit [COMMAND] -help` to print the help message of COMMAND
$ ./mygit add --help
Usage: ./mygit add [OPTIONS]
Options:
-help, --help print this message
--a, --/a set [Add all files] to true / false [default: false]
--f <file to be added>
Supports arguments of type int
, float64
, bool
, string
, []int
,
[]float
, []bool
, []string
, or any type T
that *T
implemented scli.Parse
.
For example, if Addr {string; string}
struct defines a (*Addr).FromString(string) error
method parsing 127.0.0.1:80
to Addr {"127.0.0.1", "80"}
,
and a (*Addr).Example() string
returns "1.2.3.4:5678"
, method.CLI can have a type Addr
argument.
./my-program -addr 127.0.0.1:80
Supports defining CLI program like below, where remote
, local
are layer 1 subcommands,
add
, remove
are layer 2 subcommands.
./my-program remote add -name Alice
./my-program local add -name Bob
./my-program remote remove -name Cindy
Any argument/subcommand can have a configurable CLI argument name and usage message.
Supports default value for any type of arguments by simply add a default
tag, including custom types.
-
type Arg struct { addr Addr `default:"127.0.0.1:80"` }
To parse arguments, there are 2 stages.
BuildParser(*struct{...}) error)
to build a parserParse()
,ParseArgs(...)
to parse arguments
BuildParser
will check struct field's type and tags,
if error found in type and tags, BuildParser
panics and tells
the detailed error. You can think BuildParser
compile struct{...}
to
corresponding Parser
, and compile may error.
Parse()
, ParseArgs(...)
parse input arguments from CLI or []string
,
they never panics, if parse fails, error is returned.
Parse()
do a bit more than ParseArgs(...)
. If error occurred in
Parse()
, show parse errors and program USAGE, then program exits.
If a custom type Custom
is in arguments struct, and the custom type's
Custom.FromString(string)
method may panic
.
If FromString
panic, Parse()
and ParseArg()
will panic
.