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.
This commit is contained in:
parent
b1e90a7943
commit
9b6c92647a
@ -136,6 +136,24 @@ func noRRSetupTest(input string) resulter {
|
|||||||
return fullTester(c, input)
|
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 {
|
func fullTester(c *Command, input string) resulter {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
// Testing flag with invalid input
|
// 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) {
|
func checkOutputContains(t *testing.T, c *Command, check string) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
c.SetOutput(buf)
|
c.SetOutput(buf)
|
||||||
@ -437,6 +461,7 @@ func TestRootHelp(t *testing.T) {
|
|||||||
x := fullSetupTest("--help")
|
x := fullSetupTest("--help")
|
||||||
|
|
||||||
checkResultContains(t, x, "Available Commands:")
|
checkResultContains(t, x, "Available Commands:")
|
||||||
|
checkResultContains(t, x, "for more information about that command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
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")
|
x = fullSetupTest("echo --help")
|
||||||
|
|
||||||
checkResultContains(t, x, "Available Commands:")
|
checkResultContains(t, x, "Available Commands:")
|
||||||
|
checkResultContains(t, x, "for more information about that command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
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) {
|
func TestFlagsBeforeCommand(t *testing.T) {
|
||||||
// short without space
|
// short without space
|
||||||
x := fullSetupTest("-i10 echo")
|
x := fullSetupTest("-i10 echo")
|
||||||
|
@ -203,9 +203,9 @@ Available Commands: {{range .Commands}}{{if .Runnable}}
|
|||||||
{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }}
|
{{.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}}
|
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}}
|
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}}
|
||||||
{{end}}
|
{{end}}{{ if .HasSubCommands }}
|
||||||
Use "{{.Root.Name}} help [command]" for more information about that command.
|
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() {
|
func (c *Command) initHelp() {
|
||||||
if c.helpCommand == nil {
|
if c.helpCommand == nil {
|
||||||
|
if !c.HasSubCommands() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.helpCommand = &Command{
|
c.helpCommand = &Command{
|
||||||
Use: "help [command]",
|
Use: "help [command]",
|
||||||
Short: "Help about any command",
|
Short: "Help about any command",
|
||||||
@ -479,6 +483,7 @@ func (c *Command) initHelp() {
|
|||||||
// Used for testing
|
// Used for testing
|
||||||
func (c *Command) ResetCommands() {
|
func (c *Command) ResetCommands() {
|
||||||
c.commands = nil
|
c.commands = nil
|
||||||
|
c.helpCommand = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) Commands() []*Command {
|
func (c *Command) Commands() []*Command {
|
||||||
|
Loading…
Reference in New Issue
Block a user