mirror of
https://github.com/spf13/cobra
synced 2025-05-05 04:47:22 +00:00
Add Additional Command section in help
Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>
This commit is contained in:
parent
19b8f53afc
commit
7952f7d9ff
2 changed files with 47 additions and 12 deletions
25
command.go
25
command.go
|
@ -332,7 +332,7 @@ func (c *Command) SetHelpCommandGroupID(groupID string) {
|
||||||
|
|
||||||
// SetCompletionCommandGroup sets the group id of the completion command.
|
// SetCompletionCommandGroup sets the group id of the completion command.
|
||||||
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
||||||
// completionCommandGroupID is used if no completion commmand is defined by the user
|
// completionCommandGroupID is used if no completion command is defined by the user
|
||||||
c.Root().completionCommandGroupID = groupID
|
c.Root().completionCommandGroupID = groupID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,13 +544,16 @@ Aliases:
|
||||||
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}
|
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
|
||||||
|
|
||||||
Available Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
|
Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
|
||||||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{range $group := .Groups}}
|
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
|
||||||
|
|
||||||
{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
|
{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
|
||||||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
|
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
|
||||||
|
|
||||||
|
Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
|
||||||
|
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
|
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
|
||||||
|
@ -1217,7 +1220,7 @@ func (c *Command) AddCommand(cmds ...*Command) {
|
||||||
cmds[i].parent = c
|
cmds[i].parent = c
|
||||||
// if Group is not defined let the developer know right away
|
// if Group is not defined let the developer know right away
|
||||||
if x.GroupID != "" && !c.ContainsGroup(x.GroupID) {
|
if x.GroupID != "" && !c.ContainsGroup(x.GroupID) {
|
||||||
panic(fmt.Sprintf("Group id %s is not defined", x.GroupID))
|
panic(fmt.Sprintf("Group id '%s' is not defined for subcommand '%s'", x.GroupID, cmds[i].CommandPath()))
|
||||||
}
|
}
|
||||||
// update max lengths
|
// update max lengths
|
||||||
usageLen := len(x.Use)
|
usageLen := len(x.Use)
|
||||||
|
@ -1246,6 +1249,16 @@ func (c *Command) Groups() []*Group {
|
||||||
return c.commandgroups
|
return c.commandgroups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllChildCommandsHaveGroup returns if all subcommands are assigned to a group
|
||||||
|
func (c *Command) AllChildCommandsHaveGroup() bool {
|
||||||
|
for _, sub := range c.commands {
|
||||||
|
if (sub.IsAvailableCommand() || sub == c.helpCommand) && sub.GroupID == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// ContainGroups return if groupID exists in the list of command groups.
|
// ContainGroups return if groupID exists in the list of command groups.
|
||||||
func (c *Command) ContainsGroup(groupID string) bool {
|
func (c *Command) ContainsGroup(groupID string) bool {
|
||||||
for _, x := range c.commandgroups {
|
for _, x := range c.commandgroups {
|
||||||
|
|
|
@ -1783,7 +1783,7 @@ func TestUsageWithGroup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// help should be ungrouped here
|
// help should be ungrouped here
|
||||||
checkStringContains(t, output, "\nAvailable Commands:\n help")
|
checkStringContains(t, output, "\nAdditional Commands:\n help")
|
||||||
checkStringContains(t, output, "\ngroup1\n cmd1")
|
checkStringContains(t, output, "\ngroup1\n cmd1")
|
||||||
checkStringContains(t, output, "\ngroup2\n cmd2")
|
checkStringContains(t, output, "\ngroup2\n cmd2")
|
||||||
}
|
}
|
||||||
|
@ -1802,11 +1802,11 @@ func TestUsageHelpGroup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now help should be grouped under "group"
|
// now help should be grouped under "group"
|
||||||
checkStringOmits(t, output, "\nAvailable Commands:\n help")
|
checkStringOmits(t, output, "\nAdditional Commands:\n help")
|
||||||
checkStringContains(t, output, "\nAvailable Commands:\n\ngroup\n help")
|
checkStringContains(t, output, "\ngroup\n help")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUsageCompletionpGroup(t *testing.T) {
|
func TestUsageCompletionGroup(t *testing.T) {
|
||||||
var rootCmd = &Command{Use: "root", Short: "test", Run: emptyRun}
|
var rootCmd = &Command{Use: "root", Short: "test", Run: emptyRun}
|
||||||
|
|
||||||
rootCmd.AddGroup(&Group{ID: "group", Title: "group"})
|
rootCmd.AddGroup(&Group{ID: "group", Title: "group"})
|
||||||
|
@ -1822,8 +1822,30 @@ func TestUsageCompletionpGroup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now completion should be grouped under "group"
|
// now completion should be grouped under "group"
|
||||||
checkStringOmits(t, output, "\nAvailable Commands:\n completion")
|
checkStringOmits(t, output, "\nAdditional Commands:\n completion")
|
||||||
checkStringContains(t, output, "\nAvailable Commands:\n\ngroup\n completion")
|
checkStringContains(t, output, "\ngroup\n completion")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUngroupedCommand(t *testing.T) {
|
||||||
|
var rootCmd = &Command{Use: "root", Short: "test", Run: emptyRun}
|
||||||
|
|
||||||
|
rootCmd.AddGroup(&Group{ID: "group", Title: "group"})
|
||||||
|
rootCmd.AddGroup(&Group{ID: "help", Title: "help"})
|
||||||
|
|
||||||
|
rootCmd.AddCommand(&Command{Use: "xxx", GroupID: "group", Run: emptyRun})
|
||||||
|
rootCmd.SetHelpCommandGroupID("help")
|
||||||
|
rootCmd.SetCompletionCommandGroupID("group")
|
||||||
|
|
||||||
|
// Add a command without a group
|
||||||
|
rootCmd.AddCommand(&Command{Use: "yyy", Run: emptyRun})
|
||||||
|
|
||||||
|
output, err := executeCommand(rootCmd, "--help")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The yyy command should be in the additional command "group"
|
||||||
|
checkStringContains(t, output, "\nAdditional Commands:\n yyy")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddGroup(t *testing.T) {
|
func TestAddGroup(t *testing.T) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue