Use command passed into p.Parse(...) write methods

It is currently impossible to programatically write help and usage
messages for subcommands, due to parser.WriteHelp and parser.WriteUsage
not taking the state of the parser into account.

Check for the existence of p.lastCmd and use it for the writers when
available.

Enables ability to write unit tests for subcommand help.
This commit is contained in:
Dylan Allbee 2020-01-23 21:09:21 -08:00
parent 338e831a84
commit 5df19ebe00
2 changed files with 48 additions and 3 deletions

View File

@ -27,7 +27,11 @@ func (p *Parser) failWithCommand(msg string, cmd *command) {
// WriteUsage writes usage information to the given writer
func (p *Parser) WriteUsage(w io.Writer) {
p.writeUsageForCommand(w, p.cmd)
cmd := p.cmd
if p.lastCmd != nil {
cmd = p.lastCmd
}
p.writeUsageForCommand(w, cmd)
}
// writeUsageForCommand writes usage information for the given subcommand
@ -116,7 +120,11 @@ func printTwoCols(w io.Writer, left, help string, defaultVal string) {
// WriteHelp writes the usage string followed by the full help string for each option
func (p *Parser) WriteHelp(w io.Writer) {
p.writeHelpForCommand(w, p.cmd)
cmd := p.cmd
if p.lastCmd != nil {
cmd = p.lastCmd
}
p.writeHelpForCommand(w, cmd)
}
// writeHelp writes the usage string for the given subcommand

View File

@ -266,8 +266,45 @@ Options:
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 TestUsagWithNestedSubcommands(t *testing.T) {
expectedHelp := `Usage: example child nested [--enable] OUTPUT
Positional arguments:
OUTPUT
Options:
--enable
Global options:
--values VALUES Values
--verbose, -v verbosity level
--help, -h display this help and exit
`
var args struct {
Verbose bool `arg:"-v" help:"verbosity level"`
Child *struct {
Values []float64 `help:"Values"`
Nested *struct {
Enable bool
Output string `arg:"positional,required"`
} `arg:"subcommand:nested"`
} `arg:"subcommand:child"`
}
os.Args[0] = "example"
p, err := NewParser(Config{}, &args)
require.NoError(t, err)
err = p.Parse([]string{"child", "nested", "value"})
var help bytes.Buffer
p.WriteHelp(&help)
fmt.Println(help.String())
assert.Equal(t, expectedHelp, help.String())
}