From b9cf465211fc07f87b226389269aac461945d5a2 Mon Sep 17 00:00:00 2001 From: Thomas Bruyelle Date: Tue, 1 Aug 2023 11:12:13 +0200 Subject: [PATCH] chore(cmd): print shortHelp if longHelp is empty Currenlty, `shortHelp` is used when the command is listed from its parent command, and `longHelp` is used when the command is executed with its help flag. What I found a little annoying is if `longHelp` is not provided, which is the case for the majority of commands, there's no text at all when the command is invoked with the help flag. This change ensures the `shortHelp` is printed if `longHelp` is empty. --- gnovm/cmd/gno/doc.go | 2 +- tm2/pkg/commands/command.go | 2 + tm2/pkg/commands/commands_test.go | 84 ++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 14 deletions(-) diff --git a/gnovm/cmd/gno/doc.go b/gnovm/cmd/gno/doc.go index f733cb54eb5..0de49470c2a 100644 --- a/gnovm/cmd/gno/doc.go +++ b/gnovm/cmd/gno/doc.go @@ -28,7 +28,7 @@ func newDocCmd(io *commands.IO) *commands.Command { commands.Metadata{ Name: "doc", ShortUsage: "doc [flags] ", - ShortHelp: "get documentation for the specified package or symbol (type, function, method, or variable/constant).", + ShortHelp: "get documentation for the specified package or symbol (type, function, method, or variable/constant)", }, c, func(_ context.Context, args []string) error { diff --git a/tm2/pkg/commands/command.go b/tm2/pkg/commands/command.go index 96cfb4b2228..e6fe36e3d6c 100644 --- a/tm2/pkg/commands/command.go +++ b/tm2/pkg/commands/command.go @@ -252,6 +252,8 @@ func usage(c *Command) string { if c.longHelp != "" { fmt.Fprintf(&b, "%s\n\n", c.longHelp) + } else if c.shortHelp != "" { + fmt.Fprintf(&b, "%s.\n\n", c.shortHelp) } if len(c.subcommands) > 0 { diff --git a/tm2/pkg/commands/commands_test.go b/tm2/pkg/commands/commands_test.go index 5fdeb544c3c..96802b9d720 100644 --- a/tm2/pkg/commands/commands_test.go +++ b/tm2/pkg/commands/commands_test.go @@ -420,17 +420,21 @@ func TestHelpUsage(t *testing.T) { var buf bytes.Buffer fs.SetOutput(&buf) - command := &Command{ - name: "TestHelpUsage", - shortUsage: "TestHelpUsage [flags] ", - shortHelp: "Some short help.", - longHelp: "Some long help.", - flagSet: fs, - } - - err := command.ParseAndRun(context.Background(), []string{"-h"}) - assert.ErrorIs(t, err, flag.ErrHelp) - expectedOutput := strings.TrimSpace(` + tests := []struct { + name string + command *Command + expectedOutput string + }{ + { + name: "normal case", + command: &Command{ + name: "TestHelpUsage", + shortUsage: "TestHelpUsage [flags] ", + shortHelp: "Some short help", + longHelp: "Some long help.", + flagSet: fs, + }, + expectedOutput: strings.TrimSpace(` USAGE TestHelpUsage [flags] @@ -443,8 +447,62 @@ FLAGS -i 0 int -s ... string -x ... collection of strings (repeatable) -`) + "\n\n" - assert.Equal(t, expectedOutput, buf.String()) +`) + "\n\n", + }, + { + name: "no long help", + command: &Command{ + name: "TestHelpUsage", + shortUsage: "TestHelpUsage [flags] ", + shortHelp: "Some short help", + flagSet: fs, + }, + expectedOutput: strings.TrimSpace(` +USAGE + TestHelpUsage [flags] + +Some short help. + +FLAGS + -b=false bool + -d 0s time.Duration + -f 0 float64 + -i 0 int + -s ... string + -x ... collection of strings (repeatable) +`) + "\n\n", + }, + { + name: "no short and no long help", + command: &Command{ + name: "TestHelpUsage", + shortUsage: "TestHelpUsage [flags] ", + flagSet: fs, + }, + expectedOutput: strings.TrimSpace(` +USAGE + TestHelpUsage [flags] + +FLAGS + -b=false bool + -d 0s time.Duration + -f 0 float64 + -i 0 int + -s ... string + -x ... collection of strings (repeatable) +`) + "\n\n", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + buf.Reset() + + err := tt.command.ParseAndRun(context.Background(), []string{"-h"}) + + assert.ErrorIs(t, err, flag.ErrHelp) + assert.Equal(t, tt.expectedOutput, buf.String()) + }) + } } // Forked from peterbourgon/ff/ffcli