diff --git a/help.go b/help.go index 7384eb1139..1d2938cfac 100644 --- a/help.go +++ b/help.go @@ -454,6 +454,15 @@ func checkShellCompleteFlag(c *Command, arguments []string) (bool, []string) { return false, arguments } + for _, arg := range arguments { + // If arguments include "--", shell completion is disabled + // because after "--" only positional arguments are accepted. + // https://unix.stackexchange.com/a/11382 + if arg == "--" { + return false, arguments + } + } + return true, arguments[:pos] } diff --git a/help_test.go b/help_test.go index fe5157cd0c..91e8e65d5f 100644 --- a/help_test.go +++ b/help_test.go @@ -1662,3 +1662,68 @@ GLOBAL OPTIONS: `, output.String()) } + +func Test_checkShellCompleteFlag(t *testing.T) { + t.Parallel() + tests := []struct { + name string + cmd *Command + arguments []string + wantShellCompletion bool + wantArgs []string + }{ + { + name: "disable-shell-completion", + arguments: []string{"--generate-shell-completion"}, + cmd: &Command{}, + wantShellCompletion: false, + wantArgs: []string{"--generate-shell-completion"}, + }, + { + name: "child-disable-shell-completion", + arguments: []string{"--generate-shell-completion"}, + cmd: &Command{ + parent: &Command{}, + }, + wantShellCompletion: false, + wantArgs: []string{"--generate-shell-completion"}, + }, + { + name: "last argument isn't --generate-shell-completion", + arguments: []string{"foo"}, + cmd: &Command{ + EnableShellCompletion: true, + }, + wantShellCompletion: false, + wantArgs: []string{"foo"}, + }, + { + name: "arguments include double dash", + arguments: []string{"--", "foo", "--generate-shell-completion"}, + cmd: &Command{ + EnableShellCompletion: true, + }, + wantShellCompletion: false, + wantArgs: []string{"--", "foo", "--generate-shell-completion"}, + }, + { + name: "shell completion", + arguments: []string{"foo", "--generate-shell-completion"}, + cmd: &Command{ + EnableShellCompletion: true, + }, + wantShellCompletion: true, + wantArgs: []string{"foo"}, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + shellCompletion, args := checkShellCompleteFlag(tt.cmd, tt.arguments) + assert.Equal(t, tt.wantShellCompletion, shellCompletion) + assert.Equal(t, tt.wantArgs, args) + }) + } +}