Merge pull request #59 from rickb777/master
Altered help tag parsing to allow comma and colon
This commit is contained in:
commit
59fccacb26
15
README.md
15
README.md
|
@ -99,9 +99,9 @@ Workers: 4
|
||||||
var args struct {
|
var args struct {
|
||||||
Input string `arg:"positional"`
|
Input string `arg:"positional"`
|
||||||
Output []string `arg:"positional"`
|
Output []string `arg:"positional"`
|
||||||
Verbose bool `arg:"-v,help:verbosity level"`
|
Verbose bool `arg:"-v" help:"verbosity level"`
|
||||||
Dataset string `arg:"help:dataset to use"`
|
Dataset string `help:"dataset to use"`
|
||||||
Optimize int `arg:"-O,help:optimization level"`
|
Optimize int `arg:"-O" help:"optimization level"`
|
||||||
}
|
}
|
||||||
arg.MustParse(&args)
|
arg.MustParse(&args)
|
||||||
```
|
```
|
||||||
|
@ -122,6 +122,9 @@ Options:
|
||||||
--help, -h print this help message
|
--help, -h print this help message
|
||||||
```
|
```
|
||||||
|
|
||||||
|
As the example above shows, the `help` tag can be used in conjunction with `arg`, or instead. When used
|
||||||
|
together, they can appear in either order.
|
||||||
|
|
||||||
### Default values
|
### Default values
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@ -306,7 +309,7 @@ Options:
|
||||||
--help, -h display this help and exit
|
--help, -h display this help and exit
|
||||||
```
|
```
|
||||||
|
|
||||||
### Documentation
|
### API Documentation
|
||||||
|
|
||||||
https://godoc.org/github.com/alexflint/go-arg
|
https://godoc.org/github.com/alexflint/go-arg
|
||||||
|
|
||||||
|
@ -319,3 +322,7 @@ The shortcomings of the `flag` library that ships in the standard library are we
|
||||||
Many third-party argument parsing libraries are geared for writing sophisticated command line interfaces. The excellent `codegangsta/cli` is perfect for working with multiple sub-commands and nested flags, but is probably overkill for a simple script with a handful of flags.
|
Many third-party argument parsing libraries are geared for writing sophisticated command line interfaces. The excellent `codegangsta/cli` is perfect for working with multiple sub-commands and nested flags, but is probably overkill for a simple script with a handful of flags.
|
||||||
|
|
||||||
The main idea behind `go-arg` is that Go already has an excellent way to describe data structures using Go structs, so there is no need to develop more levels of abstraction on top of this. Instead of one API to specify which arguments your program accepts, and then another API to get the values of those arguments, why not replace both with a single struct?
|
The main idea behind `go-arg` is that Go already has an excellent way to describe data structures using Go structs, so there is no need to develop more levels of abstraction on top of this. Instead of one API to specify which arguments your program accepts, and then another API to get the values of those arguments, why not replace both with a single struct?
|
||||||
|
|
||||||
|
### Backward Compatibility Notes
|
||||||
|
|
||||||
|
The tags have changed recently. Earlier versions 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 removes most of the limits on the text you can write. In particular, you will need to use the new `help` tag if your help text includes any commas.
|
||||||
|
|
15
doc.go
15
doc.go
|
@ -19,18 +19,21 @@
|
||||||
// Fields can be bool, string, any float type, or any signed or unsigned integer type.
|
// Fields can be bool, string, any float type, or any signed or unsigned integer type.
|
||||||
// They can also be slices of any of the above, or slices of pointers to any of the above.
|
// They can also be slices of any of the above, or slices of pointers to any of the above.
|
||||||
//
|
//
|
||||||
// Tags can be specified using the `arg` package name:
|
// Tags can be specified using the `arg` and `help` tag names:
|
||||||
//
|
//
|
||||||
// var args struct {
|
// var args struct {
|
||||||
// Input string `arg:"positional"`
|
// Input string `arg:"positional"`
|
||||||
// Log string `arg:"positional,required"`
|
// Log string `arg:"positional,required"`
|
||||||
// Debug bool `arg:"-d,help:turn on debug mode"`
|
// Debug bool `arg:"-d" help:"turn on debug mode"`
|
||||||
// RealMode bool `arg:"--real"
|
// RealMode bool `arg:"--real"
|
||||||
// Wr io.Writer `arg:"-"`
|
// Wr io.Writer `arg:"-"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// The valid tag strings are `positional`, `required`, and `help`. Further, any tag string
|
// Any tag string that starts with a single hyphen is the short form for an argument
|
||||||
// that starts with a single hyphen is the short form for an argument (e.g. `./example -d`),
|
// (e.g. `./example -d`), and any tag string that starts with two hyphens is the long
|
||||||
// and any tag string that starts with two hyphens is the long form for the argument
|
// form for the argument (instead of the field name).
|
||||||
// (instead of the field name). Fields can be excluded from processing with `arg:"-"`.
|
//
|
||||||
|
// Other valid tag strings are `positional` and `required`.
|
||||||
|
//
|
||||||
|
// Fields can be excluded from processing with `arg:"-"`.
|
||||||
package arg
|
package arg
|
||||||
|
|
7
parse.go
7
parse.go
|
@ -153,6 +153,11 @@ func NewParser(config Config, dests ...interface{}) (*Parser, error) {
|
||||||
dest: val,
|
dest: val,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
help, exists := field.Tag.Lookup("help")
|
||||||
|
if exists {
|
||||||
|
spec.help = help
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether this field is supported. It's good to do this here rather than
|
// Check whether this field is supported. It's good to do this here rather than
|
||||||
// wait until setScalar because it means that a program with invalid argument
|
// wait until setScalar because it means that a program with invalid argument
|
||||||
// fields will always fail regardless of whether the arguments it received
|
// fields will always fail regardless of whether the arguments it received
|
||||||
|
@ -193,7 +198,7 @@ func NewParser(config Config, dests ...interface{}) (*Parser, error) {
|
||||||
spec.positional = true
|
spec.positional = true
|
||||||
case key == "separate":
|
case key == "separate":
|
||||||
spec.separate = true
|
spec.separate = true
|
||||||
case key == "help":
|
case key == "help": // deprecated
|
||||||
spec.help = value
|
spec.help = value
|
||||||
case key == "env":
|
case key == "env":
|
||||||
// Use override name if provided
|
// Use override name if provided
|
||||||
|
|
|
@ -33,15 +33,15 @@ Options:
|
||||||
`
|
`
|
||||||
var args struct {
|
var args struct {
|
||||||
Input string `arg:"positional"`
|
Input string `arg:"positional"`
|
||||||
Output []string `arg:"positional,help:list of outputs"`
|
Output []string `arg:"positional" help:"list of outputs"`
|
||||||
Name string `arg:"help:name to use"`
|
Name string `help:"name to use"`
|
||||||
Value int `arg:"help:secret value"`
|
Value int `help:"secret value"`
|
||||||
Verbose bool `arg:"-v,help:verbosity level"`
|
Verbose bool `arg:"-v" help:"verbosity level"`
|
||||||
Dataset string `arg:"help:dataset to use"`
|
Dataset string `help:"dataset to use"`
|
||||||
Optimize int `arg:"-O,help:optimization level"`
|
Optimize int `arg:"-O" help:"optimization level"`
|
||||||
Ids []int64 `arg:"help:Ids"`
|
Ids []int64 `help:"Ids"`
|
||||||
Values []float64 `arg:"help:Values"`
|
Values []float64 `help:"Values"`
|
||||||
Workers int `arg:"-w,env:WORKERS,help:number of workers to start"`
|
Workers int `arg:"-w,env:WORKERS" help:"number of workers to start"`
|
||||||
}
|
}
|
||||||
args.Name = "Foo Bar"
|
args.Name = "Foo Bar"
|
||||||
args.Value = 42
|
args.Value = 42
|
||||||
|
@ -60,18 +60,41 @@ Options:
|
||||||
assert.Equal(t, expectedHelp, help.String())
|
assert.Equal(t, expectedHelp, help.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUsageLongPositionalWithHelp(t *testing.T) {
|
func TestUsageLongPositionalWithHelp_legacyForm(t *testing.T) {
|
||||||
expectedHelp := `Usage: example VERYLONGPOSITIONALWITHHELP
|
expectedHelp := `Usage: example VERYLONGPOSITIONALWITHHELP
|
||||||
|
|
||||||
Positional arguments:
|
Positional arguments:
|
||||||
VERYLONGPOSITIONALWITHHELP
|
VERYLONGPOSITIONALWITHHELP
|
||||||
this positional argument is very long
|
this positional argument is very long but cannot include commas
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--help, -h display this help and exit
|
--help, -h display this help and exit
|
||||||
`
|
`
|
||||||
var args struct {
|
var args struct {
|
||||||
VeryLongPositionalWithHelp string `arg:"positional,help:this positional argument is very long"`
|
VeryLongPositionalWithHelp string `arg:"positional,help:this positional argument is very long but cannot include commas"`
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := NewParser(Config{}, &args)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
os.Args[0] = "example"
|
||||||
|
var help bytes.Buffer
|
||||||
|
p.WriteHelp(&help)
|
||||||
|
assert.Equal(t, expectedHelp, help.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsageLongPositionalWithHelp_newForm(t *testing.T) {
|
||||||
|
expectedHelp := `Usage: example VERYLONGPOSITIONALWITHHELP
|
||||||
|
|
||||||
|
Positional arguments:
|
||||||
|
VERYLONGPOSITIONALWITHHELP
|
||||||
|
this positional argument is very long, and includes: commas, colons etc
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help, -h display this help and exit
|
||||||
|
`
|
||||||
|
var args struct {
|
||||||
|
VeryLongPositionalWithHelp string `arg:"positional" help:"this positional argument is very long, and includes: commas, colons etc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := NewParser(Config{}, &args)
|
p, err := NewParser(Config{}, &args)
|
||||||
|
@ -168,7 +191,7 @@ Options:
|
||||||
--help, -h display this help and exit
|
--help, -h display this help and exit
|
||||||
`
|
`
|
||||||
var args struct {
|
var args struct {
|
||||||
RequiredMultiple []string `arg:"positional,required,help:required multiple positional"`
|
RequiredMultiple []string `arg:"positional,required" help:"required multiple positional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := NewParser(Config{}, &args)
|
p, err := NewParser(Config{}, &args)
|
||||||
|
|
Loading…
Reference in New Issue