Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Description() on subcommands #167

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,15 @@ func (p *Parser) writeHelpForSubcommand(w io.Writer, cmd *command) {
}
}

if p.description != "" {
var description string
if v := p.val(cmd.dest); v.IsValid() && !isZero(v) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to include !isZero(v) in here because v.IsValid already checks that (see https://cs.opensource.google/go/go/+/refs/tags/go1.17.5:src/reflect/value.go;l=1435)

The basic issue with this approach is that it won't work if the struct for this subcommand has a parent that is nil, since in that case we will end up here and then v.IsValid() will return true.

It would be better to store the type for each subcommand in the command struct and then instantiate a new struct of that type right here and check whether it satisfies the Described interface

if d, ok := v.Interface().(Described); ok {
description = d.Description()
}
}
if description != "" {
fmt.Fprintln(w, description)
} else if p.description != "" {
fmt.Fprintln(w, p.description)
}
p.writeUsageForSubcommand(w, cmd)
Expand Down
2 changes: 2 additions & 0 deletions usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ func TestUsageWithNestedSubcommands(t *testing.T) {
expectedUsage := "Usage: example child nested [--enable] OUTPUT"

expectedHelp := `
this program does this and that
Usage: example child nested [--enable] OUTPUT

Positional arguments:
Expand All @@ -336,6 +337,7 @@ Global options:
Child *struct {
Values []float64 `help:"Values"`
Nested *struct {
described
Enable bool
Output string `arg:"positional,required"`
} `arg:"subcommand:nested"`
Expand Down