Complete subcommands when TraverseChildren is set (#1171)

* Complete subcommands when TraverseChildren is true in custom completion

The current custom completion logic does not complete
subcommands when a local flag is set. This is good unless
TraverseChildren is set to true where local flags
can be set on parent commands.

This commit allows subcommands to be completed
if TraverseChildren is set to true on the root cmd.

Closes #1170

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>

* Complete subcommands when TraverseChildren is true in bash completion

The current bash completion logic does not complete
subcommands when a local flag is set. There is also a bug
where subcommands are sometimes still getting completed. see: #1172

If TraverseChildren is true we should allow subcommands
to be completed even if a local flag is set.

Closes #1172

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
This commit is contained in:
Luap99
2020-09-09 17:34:51 +02:00
committed by GitHub
parent 02a0d2fbc9
commit 50258f15eb
4 changed files with 114 additions and 13 deletions

View File

@ -139,6 +139,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) {
Use: "root",
Run: emptyRun,
}
rootCmd.Flags().String("localroot", "", "local root flag")
childCmd1 := &Command{
Use: "childCmd1",
Short: "First command",
@ -187,6 +189,64 @@ func TestNoCmdNameCompletionInGo(t *testing.T) {
t.Errorf("expected: %q, got: %q", expected, output)
}
// Test that sub-command names are completed if a local non-persistent flag is present and TraverseChildren is set to true
// set TraverseChildren to true on the root cmd
rootCmd.TraverseChildren = true
output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--localroot", "value", "")
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Reset TraverseChildren for next command
rootCmd.TraverseChildren = false
expected = strings.Join([]string{
"childCmd1",
"help",
":4",
"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n")
if output != expected {
t.Errorf("expected: %q, got: %q", expected, output)
}
// Test that sub-command names from a child cmd are completed if a local non-persistent flag is present
// and TraverseChildren is set to true on the root cmd
rootCmd.TraverseChildren = true
output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--localroot", "value", "childCmd1", "--nonPersistent", "value", "")
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
// Reset TraverseChildren for next command
rootCmd.TraverseChildren = false
// Reset the flag for the next command
nonPersistentFlag.Changed = false
expected = strings.Join([]string{
"childCmd2",
":4",
"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n")
if output != expected {
t.Errorf("expected: %q, got: %q", expected, output)
}
// Test that we don't use Traverse when we shouldn't.
// This command should not return a completion since the command line is invalid without TraverseChildren.
output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--localroot", "value", "childCmd1", "")
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
expected = strings.Join([]string{
":0",
"Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n")
if output != expected {
t.Errorf("expected: %q, got: %q", expected, output)
}
// Test that sub-command names are not completed if a local non-persistent short flag is present
output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "childCmd1", "-n", "value", "")
if err != nil {