add support for description string

This commit is contained in:
Emmanouil "Manolis" Maragkakis 2017-01-23 20:41:12 -05:00
parent 7c77c70f85
commit db27431153
4 changed files with 73 additions and 3 deletions

View File

@ -263,6 +263,33 @@ usage: example [--name NAME]
error: error processing --name: missing period in "oops"
```
### Description strings
```go
type args struct {
Foo string
}
func (args) Description() string {
return "this program does this and that"
}
func main() {
var args args
arg.MustParse(&args)
}
```
```shell
$ ./example -h
this program does this and that
usage: example [--foo FOO]
options:
--foo FOO
--help, -h display this help and exit
```
### Documentation
https://godoc.org/github.com/alexflint/go-arg

View File

@ -67,9 +67,10 @@ type Config struct {
// Parser represents a set of command line options with destination values
type Parser struct {
spec []*spec
config Config
version string
spec []*spec
config Config
version string
description string
}
// Versioned is the interface that the destination struct should implement to
@ -80,6 +81,14 @@ type Versioned interface {
Version() string
}
// Described is the interface that the destination struct should implement to
// make a description string appear at the top of the help message.
type Described interface {
// Description returns the string that will be printed on a line by itself
// at the top of the help message.
Description() string
}
// walkFields calls a function for each field of a struct, recursively expanding struct fields.
func walkFields(v reflect.Value, visit func(field reflect.StructField, val reflect.Value, owner reflect.Type) bool) {
t := v.Type()
@ -102,6 +111,9 @@ func NewParser(config Config, dests ...interface{}) (*Parser, error) {
if dest, ok := dest.(Versioned); ok {
p.version = dest.Version()
}
if dest, ok := dest.(Described); ok {
p.description = dest.Description()
}
v := reflect.ValueOf(dest)
if v.Kind() != reflect.Ptr {
panic(fmt.Sprintf("%s is not a pointer (did you forget an ampersand?)", v.Type()))

View File

@ -29,6 +29,9 @@ func (p *Parser) WriteUsage(w io.Writer) {
}
}
if p.description != "" {
fmt.Fprintln(w, p.description)
}
if p.version != "" {
fmt.Fprintln(w, p.version)
}

View File

@ -129,3 +129,31 @@ options:
t.Fail()
}
}
type described struct{}
// Described returns the description for this program
func (described) Description() string {
return "this program does this and that"
}
func TestUsageWithDescription(t *testing.T) {
expectedHelp := `this program does this and that
usage: example
options:
--help, -h display this help and exit
`
os.Args[0] = "example"
p, err := NewParser(Config{}, &described{})
require.NoError(t, err)
var help bytes.Buffer
p.WriteHelp(&help)
actual := help.String()
t.Logf("Expected:\n%s", expectedHelp)
t.Logf("Actual:\n%s", actual)
if expectedHelp != actual {
t.Fail()
}
}