Skip to content

Commit

Permalink
Merge pull request #96 from Andrew-Morozko/master
Browse files Browse the repository at this point in the history
Added the "placeholder" tag
  • Loading branch information
alexflint authored Dec 1, 2019
2 parents c0c7a3b + 9d4521c commit ced05bf
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 17 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,34 @@ $ ./example
main.NameDotName{Head:"file", Tail:"txt"}
```
### Custom placeholders
Use the `placeholder` tag to control which placeholder text is used in the usage text.
```go
var args struct {
Input string `arg:"positional" placeholder:"SRC"`
Output []string `arg:"positional" placeholder:"DST"`
Optimize int `arg:"-O" help:"optimization level" placeholder:"LEVEL"`
MaxJobs int `arg:"-j" help:"maximum number of simultaneous jobs" placeholder:"N"`
}
arg.MustParse(&args)
```
```shell
$ ./example -h
Usage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]]

Positional arguments:
SRC
DST

Options:
--optimize LEVEL, -O LEVEL
optimization level
--maxjobs N, -j N maximum number of simultaneous jobs
--help, -h display this help and exit
```
### Description strings
```go
Expand Down
32 changes: 32 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,38 @@ func Example_helpText() {
// --help, -h display this help and exit
}

// This example shows the usage string generated by go-arg with customized placeholders
func Example_helpPlaceholder() {
// These are the args you would pass in on the command line
os.Args = split("./example --help")

var args struct {
Input string `arg:"positional" placeholder:"SRC"`
Output []string `arg:"positional" placeholder:"DST"`
Optimize int `arg:"-O" help:"optimization level" placeholder:"LEVEL"`
MaxJobs int `arg:"-j" help:"maximum number of simultaneous jobs" placeholder:"N"`
}

// This is only necessary when running inside golang's runnable example harness
osExit = func(int) {}

MustParse(&args)

// output:

// Usage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]]

// Positional arguments:
// SRC
// DST

// Options:
// --optimize LEVEL, -O LEVEL
// optimization level
// --maxjobs N, -j N maximum number of simultaneous jobs
// --help, -h display this help and exit
}

// This example shows the usage string generated by go-arg when using subcommands
func Example_helpTextWithSubcommand() {
// These are the args you would pass in on the command line
Expand Down
32 changes: 20 additions & 12 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,19 @@ func (p path) Child(child string) path {

// spec represents a command line option
type spec struct {
dest path
typ reflect.Type
long string
short string
multiple bool
required bool
positional bool
separate bool
help string
env string
boolean bool
defaultVal string // default value for this option
dest path
typ reflect.Type
long string
short string
multiple bool
required bool
positional bool
separate bool
help string
env string
boolean bool
defaultVal string // default value for this option
placeholder string // name of the data in help
}

// command represents a named subcommand, or the top-level command
Expand Down Expand Up @@ -342,6 +343,13 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) {
}
}

placeholder, hasPlaceholder := field.Tag.Lookup("placeholder")
if hasPlaceholder {
spec.placeholder = placeholder
} else {
spec.placeholder = strings.ToUpper(spec.long)
}

// Check whether this field is supported. It's good to do this here rather than
// wait until ParseValue because it means that a program with invalid argument
// fields will always fail regardless of whether the arguments it received
Expand Down
11 changes: 11 additions & 0 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ func TestLongFlag(t *testing.T) {
assert.Equal(t, "xyz", args.Foo)
}

func TestPlaceholder(t *testing.T) {
var args struct {
Input string `arg:"positional" placeholder:"SRC"`
Output []string `arg:"positional" placeholder:"DST"`
Optimize int `arg:"-O" placeholder:"LEVEL"`
MaxJobs int `arg:"-j" placeholder:"N"`
}
err := parse("-O 5 --maxjobs 2 src dest1 dest2", &args)
assert.NoError(t, err)
}

func TestCaseSensitive(t *testing.T) {
var args struct {
Lower bool `arg:"-v"`
Expand Down
9 changes: 4 additions & 5 deletions usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,16 @@ func (p *Parser) writeUsageForCommand(w io.Writer, cmd *command) {
for _, spec := range positionals {
// prefix with a space
fmt.Fprint(w, " ")
up := strings.ToUpper(spec.long)
if spec.multiple {
if !spec.required {
fmt.Fprint(w, "[")
}
fmt.Fprintf(w, "%s [%s ...]", up, up)
fmt.Fprintf(w, "%s [%s ...]", spec.placeholder, spec.placeholder)
if !spec.required {
fmt.Fprint(w, "]")
}
} else {
fmt.Fprint(w, up)
fmt.Fprint(w, spec.placeholder)
}
}
fmt.Fprint(w, "\n")
Expand Down Expand Up @@ -134,7 +133,7 @@ func (p *Parser) writeHelpForCommand(w io.Writer, cmd *command) {
if len(positionals) > 0 {
fmt.Fprint(w, "\nPositional arguments:\n")
for _, spec := range positionals {
printTwoCols(w, strings.ToUpper(spec.long), spec.help, "")
printTwoCols(w, spec.placeholder, spec.help, "")
}
}

Expand Down Expand Up @@ -180,7 +179,7 @@ func synopsis(spec *spec, form string) string {
if spec.boolean {
return form
}
return form + " " + strings.ToUpper(spec.long)
return form + " " + spec.placeholder
}

func ptrTo(s string) *string {
Expand Down

0 comments on commit ced05bf

Please sign in to comment.