diff --git a/command.go b/command.go index 6866f7d0f3..160334c44b 100644 --- a/command.go +++ b/command.go @@ -240,6 +240,10 @@ type Command struct { // line of a command when printing help or generating docs DisableFlagsInUseLine bool + // DisableArgsInUseLine will disable the addition of [args] to the usage + // line of a command when printing help or generating docs + DisableArgsInUseLine bool + // DisableSuggestions disables the suggestions based on Levenshtein distance // that go along with 'unknown command' messages. DisableSuggestions bool @@ -1413,12 +1417,12 @@ func (c *Command) UseLine() string { } else { useline = c.Use } - if c.DisableFlagsInUseLine { - return useline - } - if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") { + if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") && !c.DisableFlagsInUseLine { useline += " [flags]" } + if c.HasAvailableArgs() && !strings.Contains(useline, "[args]") && !c.DisableArgsInUseLine { + useline += " [args]" + } return useline } @@ -1762,6 +1766,11 @@ func (c *Command) HasAvailableInheritedFlags() bool { return c.InheritedFlags().HasAvailableFlags() } +// HasAvailableArgs checks if the command has non-nil Args. +func (c *Command) HasAvailableArgs() bool { + return c.Args != nil +} + // Flag climbs up the command tree looking for matching flag. func (c *Command) Flag(name string) (flag *flag.Flag) { flag = c.Flags().Lookup(name) diff --git a/command_test.go b/command_test.go index 4afb7f7b8e..7bb4020816 100644 --- a/command_test.go +++ b/command_test.go @@ -2768,3 +2768,102 @@ func TestUnknownFlagShouldReturnSameErrorRegardlessOfArgPosition(t *testing.T) { }) } } + +func TestUseLine(t *testing.T) { + var testFlagSet pflag.FlagSet + testFlagSet.AddFlag(&pflag.Flag{ + Name: "flag_0", + }) + testCases := []struct { + Cmd *Command + UseLine string + }{ + { + &Command{ + DisableFlagsInUseLine: true, + DisableArgsInUseLine: true, + parent: &Command{ + Use: "parent_use_0", + }, + Use: "use_0", + flags: &testFlagSet, + Args: func(cmd *Command, args []string) error { return nil }, + }, + "parent_use_0 use_0", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + parent: &Command{ + Use: "parent_use_1", + }, + Use: "use_1", + }, + "parent_use_1 use_1", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: true, + parent: &Command{ + Use: "parent_use_3", + }, + Use: "use_3", + flags: &testFlagSet, + Args: func(cmd *Command, args []string) error { return nil }, + }, + "parent_use_3 use_3 [flags]", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + Use: "use_4", + flags: &testFlagSet, + Args: func(cmd *Command, args []string) error { return nil }, + }, + "use_4 [flags] [args]", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + Use: "use_5", + Args: func(cmd *Command, args []string) error { return nil }, + }, + "use_5 [args]", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + Use: "use_6", + }, + "use_6", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + Use: "[flags] use_7", + flags: &testFlagSet, + }, + "[flags] use_7", + }, + { + &Command{ + DisableFlagsInUseLine: false, + DisableArgsInUseLine: false, + Use: "[args] use_8", + Args: func(cmd *Command, args []string) error { return nil }, + }, + "[args] use_8", + }, + } + for i, tc := range testCases { + if tc.Cmd.UseLine() != tc.UseLine { + t.Errorf("test case no. %d mismatch.\nResult: %s\nExpect: %s", i, tc.Cmd.UseLine(), tc.UseLine) + } + } +}