diff --git a/command.go b/command.go index c05fed45a..cc412da46 100644 --- a/command.go +++ b/command.go @@ -1345,18 +1345,21 @@ func (c *Command) AddCommand(cmds ...*Command) { panic("Command can't be a child of itself") } cmds[i].parent = c - // update max lengths - usageLen := len(x.Use) - if usageLen > c.commandsMaxUseLen { - c.commandsMaxUseLen = usageLen - } - commandPathLen := len(x.CommandPath()) - if commandPathLen > c.commandsMaxCommandPathLen { - c.commandsMaxCommandPathLen = commandPathLen - } - nameLen := len(x.Name()) - if nameLen > c.commandsMaxNameLen { - c.commandsMaxNameLen = nameLen + // update max lengths, skipping hidden and deprecated commands + // since they are not shown in usage output + if !x.Hidden && len(x.Deprecated) == 0 { + usageLen := len(x.Use) + if usageLen > c.commandsMaxUseLen { + c.commandsMaxUseLen = usageLen + } + commandPathLen := len(x.CommandPath()) + if commandPathLen > c.commandsMaxCommandPathLen { + c.commandsMaxCommandPathLen = commandPathLen + } + nameLen := len(x.Name()) + if nameLen > c.commandsMaxNameLen { + c.commandsMaxNameLen = nameLen + } } // If global normalization function exists, update all children if c.globNormFunc != nil { @@ -1416,6 +1419,9 @@ main: c.commandsMaxCommandPathLen = 0 c.commandsMaxNameLen = 0 for _, command := range c.commands { + if command.Hidden || len(command.Deprecated) != 0 { + continue + } usageLen := len(command.Use) if usageLen > c.commandsMaxUseLen { c.commandsMaxUseLen = usageLen diff --git a/command_test.go b/command_test.go index a86e57f0a..c195ebbab 100644 --- a/command_test.go +++ b/command_test.go @@ -2952,3 +2952,27 @@ func TestHelpFuncExecuted(t *testing.T) { checkStringContains(t, output, helpText) } + +func TestHiddenCommandsDoNotInflatePadding(t *testing.T) { + rootCmd := &Command{Use: "root", Run: emptyRun} + childCmd := &Command{Use: "child", Run: emptyRun} + longChildCmd := &Command{Use: "long-name-child-abcdefghijklmnopqrstuvwxyz", Run: emptyRun} + hiddenChildCmd := &Command{Use: longChildCmd.Use + "-hidden", Hidden: true, Run: emptyRun} + deprecatedChildCmd := &Command{Use: longChildCmd.Use + "-deprecated", Deprecated: "deprecated", Run: emptyRun} + + rootCmd.AddCommand(childCmd, longChildCmd, hiddenChildCmd, deprecatedChildCmd) + + expectedUsePad := len(longChildCmd.Use) + expectedPathPad := len(longChildCmd.CommandPath()) + expectedNamePad := len(longChildCmd.Name()) + + if got := childCmd.UsagePadding(); got != expectedUsePad { + t.Errorf("UsagePadding() = %d, want %d", got, expectedUsePad) + } + if got := childCmd.CommandPathPadding(); got != expectedPathPad { + t.Errorf("CommandPathPadding() = %d, want %d", got, expectedPathPad) + } + if got := childCmd.NamePadding(); got != expectedNamePad { + t.Errorf("NamePadding() = %d, want %d", got, expectedNamePad) + } +}