From 9b6c92647afd5a915800171a038516acef3abbed Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Tue, 11 Nov 2014 23:32:54 -0500 Subject: [PATCH] When no subcommands are registered, omit command help output For a single root command with a Run method, the help output still contains 'help [command]' as a subcommand (because Help is always added). Since the only subcommand would be 'help', the help is better off omitted. This change allows a command to be used both as a subcommand or a root command without having to define a custom help that elides the help command when no subcommands are added. Instead, the default help command is only added when subcommands are present. --- cobra_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ command.go | 9 +++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/cobra_test.go b/cobra_test.go index 05d18d0c..dd44812c 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -136,6 +136,24 @@ func noRRSetupTest(input string) resulter { return fullTester(c, input) } +func rootOnlySetupTest(input string) resulter { + c := initializeWithRootCmd() + + return simpleTester(c, input) +} + +func simpleTester(c *Command, input string) resulter { + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + c.SetArgs(strings.Split(input, " ")) + + err := c.Execute() + output := buf.String() + + return resulter{err, output, c} +} + func fullTester(c *Command, input string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input @@ -156,6 +174,12 @@ func checkResultContains(t *testing.T, x resulter, check string) { } } +func checkResultOmits(t *testing.T, x resulter, check string) { + if strings.Contains(x.Output, check) { + t.Errorf("Unexpected response.\nExpecting to omit: \n %q\nGot:\n %q\n", check, x.Output) + } +} + func checkOutputContains(t *testing.T, c *Command, check string) { buf := new(bytes.Buffer) c.SetOutput(buf) @@ -437,6 +461,7 @@ func TestRootHelp(t *testing.T) { x := fullSetupTest("--help") checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about that command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -445,6 +470,7 @@ func TestRootHelp(t *testing.T) { x = fullSetupTest("echo --help") checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about that command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -452,6 +478,26 @@ func TestRootHelp(t *testing.T) { } +func TestRootNoCommandHelp(t *testing.T) { + x := rootOnlySetupTest("--help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about that command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } + + x = rootOnlySetupTest("echo --help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about that command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } +} + func TestFlagsBeforeCommand(t *testing.T) { // short without space x := fullSetupTest("-i10 echo") diff --git a/command.go b/command.go index 1337065d..b506b1ed 100644 --- a/command.go +++ b/command.go @@ -203,9 +203,9 @@ Available Commands: {{range .Commands}}{{if .Runnable}} {{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }} Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}} -{{end}} +{{end}}{{ if .HasSubCommands }} Use "{{.Root.Name}} help [command]" for more information about that command. -` +{{end}}` } } @@ -465,6 +465,10 @@ func (c *Command) Execute() (err error) { func (c *Command) initHelp() { if c.helpCommand == nil { + if !c.HasSubCommands() { + return + } + c.helpCommand = &Command{ Use: "help [command]", Short: "Help about any command", @@ -479,6 +483,7 @@ func (c *Command) initHelp() { // Used for testing func (c *Command) ResetCommands() { c.commands = nil + c.helpCommand = nil } func (c *Command) Commands() []*Command {