Skip to content

Commit

Permalink
feat(completion): add default completion hidden if there are no subco…
Browse files Browse the repository at this point in the history
…mmands

The default completion is useful also in cases where there are no
subcommands, for example to provide completion for flags, and custom
completions for their values.

But when there are no subcommands, make it hidden. Simply adding it
non-hidden would result in a help section to be added just for it which
is just noise: the completion command is not the primary functionality
of the program, yet it would be prominently displayed in help output. It
would also get included among argument completions, which could be a
source of confusion.
  • Loading branch information
scop committed Dec 10, 2021
1 parent 19c9c74 commit c7cee2a
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
5 changes: 3 additions & 2 deletions completions.go
Expand Up @@ -586,7 +586,7 @@ func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*p
// 2- c has no subcommands (to avoid creating one),
// 3- c already has a 'completion' command provided by the program.
func (c *Command) initDefaultCompletionCmd() {
if c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() {
if c.CompletionOptions.DisableDefaultCmd {
return
}

Expand All @@ -598,6 +598,7 @@ func (c *Command) initDefaultCompletionCmd() {
}

haveNoDescFlag := !c.CompletionOptions.DisableNoDescFlag && !c.CompletionOptions.DisableDescriptions
hidden := c.CompletionOptions.HiddenDefaultCmd || !c.HasSubCommands()

completionCmd := &Command{
Use: compCmdName,
Expand All @@ -607,7 +608,7 @@ See each sub-command's help for details on how to use the generated script.
`, c.Root().Name()),
Args: NoArgs,
ValidArgsFunction: NoFileCompletions,
Hidden: c.CompletionOptions.HiddenDefaultCmd,
Hidden: hidden,
}
c.AddCommand(completionCmd)

Expand Down
13 changes: 10 additions & 3 deletions completions_test.go
Expand Up @@ -2287,14 +2287,21 @@ func TestDefaultCompletionCmd(t *testing.T) {
Run: emptyRun,
}

// Test that no completion command is created if there are not other sub-commands
// Test that default completion command is created, hidden if there are no other sub-commands
assertNoErr(t, rootCmd.Execute())
found := false
for _, cmd := range rootCmd.commands {
if cmd.Name() == compCmdName {
t.Errorf("Should not have a 'completion' command when there are no other sub-commands of root")
found = true
if !cmd.Hidden {
t.Errorf("The 'completion' command should be hidden when there are no other sub-commands of root")
}
break
}
}
if !found {
t.Errorf("Should have a 'completion' command when there are no other sub-commands of root")
}

subCmd := &Command{
Use: "sub",
Expand All @@ -2303,7 +2310,7 @@ func TestDefaultCompletionCmd(t *testing.T) {
rootCmd.AddCommand(subCmd)

// Test that a completion command is created if there are other sub-commands
found := false
found = false
assertNoErr(t, rootCmd.Execute())
for _, cmd := range rootCmd.commands {
if cmd.Name() == compCmdName {
Expand Down
3 changes: 2 additions & 1 deletion shell_completions.md
Expand Up @@ -8,7 +8,8 @@ The currently supported shells are:
- PowerShell

Cobra will automatically provide your program with a fully functional `completion` command,
similarly to how it provides the `help` command.
similarly to how it provides the `help` command. If there are no other subcommands, the
default `completion` command will be hidden, but still functional.

## Creating your own completion command

Expand Down

0 comments on commit c7cee2a

Please sign in to comment.