Repository: urfave/cli
Pull request #1933 (2024-06-27 05:06:56)

fix: disable shell completion if double dash is included in arguments (v3)
<!--
  This template provides some ideas of things to include in your PR description.
  To start, try providing a short summary of your changes in the Title above.
  If a section of the PR template does not apply to this PR, then delete that section.
 -->

## What type of PR is this?

_(REQUIRED)_

<!--
  Delete any of the following that do not apply:
 -->

- bug

## What this PR does / why we need it:

_(REQUIRED)_

<!--
  What goal is this change working towards?
  Provide a bullet pointed summary of how each file was changed.
  Briefly explain any decisions you made with respect to the changes.
  Include anything here that you didn't include in *Release Notes*
  above, such as changes to CI or changes to internal methods.
-->

This pull request disables shell completion if double dash `--` is included in arguments.
Arguments after double dash `--` are not flags but positional arguments.

https://unix.stackexchange.com/a/11382

## Which issue(s) this PR fixes:

_(REQUIRED)_

<!--
If this PR fixes one of more issues, list them here.
One line each, like so:

Fixes #123
Fixes #39
-->

Fixes https://github.com/urfave/cli/issues/1932

## Special notes for your reviewer:

_(fill-in or delete this section)_

<!--
   Is there any particular feedback you would / wouldn't like?
   Which parts of the code should reviewers focus on?
-->

## Testing

_(fill-in or delete this section)_

<!--
  Describe how you tested this change.
-->

## Release Notes

_(REQUIRED)_
<!--
  If this PR makes user facing changes, please describe them here. This
  description will be copied into the release notes/changelog, whenever the
  next version is released. Keep this section short, and focus on high level
  changes.

  Put your text between the block. To omit notes, use NONE within the block.
-->

```release-note

```



Patch:
diff --git a/help.go b/help.go
index 7384eb1..1d2938c 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]
 }
 


Test patch:
diff --git a/help_test.go b/help_test.go
index fe5157c..91e8e65 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)
+		})
+	}
+}