From 0606c4d048cfc2eaa5c96666a849ee570ea9e494 Mon Sep 17 00:00:00 2001 From: Alan Braithwaite Date: Mon, 4 May 2026 16:34:05 -0700 Subject: [PATCH] cli: use actual binary name in completion scripts Completion scripts were using the app's logical name (from cli.New()) instead of the actual binary name (os.Args[0]). This meant renaming or symlinking the binary would produce scripts that registered completions for the wrong command name. --- cli/complete.go | 12 +++++++++--- cli/complete_test.go | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cli/complete.go b/cli/complete.go index de1c9dd..753862b 100644 --- a/cli/complete.go +++ b/cli/complete.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "os" + "path/filepath" "strings" ) @@ -44,15 +46,19 @@ func (a *App) handleCompletionScript(args []string) int { ) return 1 } + // Use the actual binary name so the completion script matches + // whatever name the binary was installed as. + binName := filepath.Base(os.Args[0]) + // Completion scripts and __complete output go to stdout, not // a.output (which defaults to stderr). The shell reads stdout. switch args[0] { case "bash": - writeBashCompletion(a.stdout, a.name) + writeBashCompletion(a.stdout, binName) case "zsh": - writeZshCompletion(a.stdout, a.name) + writeZshCompletion(a.stdout, binName) case "fish": - writeFishCompletion(a.stdout, a.name) + writeFishCompletion(a.stdout, binName) default: fmt.Fprintf( a.output, diff --git a/cli/complete_test.go b/cli/complete_test.go index 2c1138a..04c49b9 100644 --- a/cli/complete_test.go +++ b/cli/complete_test.go @@ -173,7 +173,9 @@ func TestCompletionScripts(t *testing.T) { output := buf.String() require.NotEmpty(t, output) - assert.Contains(t, output, "testapp") + // The script should reference the actual binary name, + // not the app's logical name. + assert.NotContains(t, output, "testapp") }) } }