From 30a12c90c470eb90e492f3b9f293691cdfdd2de1 Mon Sep 17 00:00:00 2001 From: "lushirong.77" Date: Tue, 30 Jun 2026 18:13:46 +0800 Subject: [PATCH 1/2] fix: avoid executing actions while completing double dash --- app_test.go | 30 ++++++++++++++++++++++++++++++ help.go | 16 +++++++++++----- help_test.go | 11 ++++++++++- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/app_test.go b/app_test.go index f6f9158b05..bafcdac652 100644 --- a/app_test.go +++ b/app_test.go @@ -1850,6 +1850,36 @@ func TestApp_OrderOfOperations(t *testing.T) { app.Commands = oldCommands } +func TestApp_Run_DoubleDashShellCompletionDoesNotExecuteAction(t *testing.T) { + origArgv := os.Args + t.Cleanup(func() { + os.Args = origArgv + }) + + var output bytes.Buffer + actionCalled := false + + app := &App{ + EnableBashCompletion: true, + HideHelp: true, + Writer: &output, + Flags: []Flag{ + &BoolFlag{Name: "verbose"}, + }, + Action: func(c *Context) error { + actionCalled = true + return nil + }, + } + + os.Args = []string{"command", "--", "--generate-bash-completion"} + + err := app.Run(os.Args) + expect(t, err, nil) + expect(t, actionCalled, false) + expect(t, output.String(), "--verbose\n") +} + func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) { var subcommandHelpTopics = [][]string{ {"command", "foo", "--help"}, diff --git a/help.go b/help.go index d27e8ce385..2178191136 100644 --- a/help.go +++ b/help.go @@ -447,12 +447,18 @@ func checkShellCompleteFlag(a *App, 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 arguments include "--" before the token being completed, shell + // completion is disabled because after "--" only positional arguments are + // accepted. We only check arguments before the token being completed so + // completing "--" itself still works. + // https://unix.stackexchange.com/a/11382 + limit := 0 + if pos > 1 { + limit = pos - 1 + } + for _, arg := range arguments[:limit] { if arg == "--" { - return false, arguments + return false, arguments[:pos] } } diff --git a/help_test.go b/help_test.go index 8a856258ae..e0f82cb587 100644 --- a/help_test.go +++ b/help_test.go @@ -1745,7 +1745,16 @@ func Test_checkShellCompleteFlag(t *testing.T) { EnableBashCompletion: true, }, wantShellCompletion: false, - wantArgs: []string{"--", "foo", "--generate-bash-completion"}, + wantArgs: []string{"--", "foo"}, + }, + { + name: "double dash is the token being completed", + arguments: []string{"foo", "--", "--generate-bash-completion"}, + app: &App{ + EnableBashCompletion: true, + }, + wantShellCompletion: true, + wantArgs: []string{"foo", "--"}, }, { name: "--generate-bash-completion", From 540a21ed24bb7667733f9c4f17f42318e271d5f2 Mon Sep 17 00:00:00 2001 From: "lushirong.77" Date: Tue, 30 Jun 2026 18:30:44 +0800 Subject: [PATCH 2/2] refactor: shrink double-dash completion check --- help.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/help.go b/help.go index 2178191136..0b546c1f0c 100644 --- a/help.go +++ b/help.go @@ -449,16 +449,12 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) { // If arguments include "--" before the token being completed, shell // completion is disabled because after "--" only positional arguments are - // accepted. We only check arguments before the token being completed so - // completing "--" itself still works. + // accepted. If "--" is itself the token being completed, keep completion + // enabled so long-flag suggestions still work. // https://unix.stackexchange.com/a/11382 - limit := 0 - if pos > 1 { - limit = pos - 1 - } - for _, arg := range arguments[:limit] { + for i, arg := range arguments[:pos] { if arg == "--" { - return false, arguments[:pos] + return i == pos-1, arguments[:pos] } }