fix(completion): return suggestions instead of the help page - #135
Open
vrobert78 wants to merge 1 commit into
Open
fix(completion): return suggestions instead of the help page#135vrobert78 wants to merge 1 commit into
vrobert78 wants to merge 1 commit into
Conversation
Tab completion produced nothing in zsh, bash and fish. The completion
scripts fetch suggestions by calling the hidden `_complete` command of
the legacy CLI, passing the shell as a glued short option (-szsh, -sbash,
-sfish). The Go layer parses those arguments with Cobra, which splits a
glued short option into single-letter flags; as every supported shell
name contains an "h", the bundle always ended with -h, so the CLI
answered with its help page:
$ upsun _complete --no-interaction -szsh -c1 -iupsun -ienv
Command: _complete
Description: Internal command to provide shell completion suggestions
The completion function silently discarded that output. The legacy CLI
itself parses the glued form correctly, so only the Go layer was at
fault.
Proxy `_complete` through a hidden Cobra command with flag parsing
disabled, so the request reaches the legacy CLI unchanged. This also
fixes completion files that users already have installed, and it covers
the input tokens, which have the same problem: completing
"upsun ssh --pro<TAB>" passes -issh, whose "h" was bundled in too.
Additionally, emit the shell as --shell=<shell> in the generated scripts,
so a completion request no longer depends on how glued short options are
parsed.
Completion requests now also skip the update check and the shell config
leftovers notice: they run on every Tab, and the bash script captures
stderr along with stdout, so any message would end up in the suggestions.
Verified with real Tab presses in zsh, bash and fish (newly generated
scripts, previously installed scripts, and eval "$(upsun completion)").
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes shell tab-completion for the Upsun CLI by preventing Cobra/pflag from mis-parsing legacy _complete requests (notably the glued -s<shell> form that previously produced a bundled -h and triggered help output instead of suggestions). It does so by proxying _complete through a hidden Cobra command with flag parsing disabled, updating generated completion scripts to use --shell=<shell>, and adding regression coverage via unit + integration tests.
Changes:
- Add a hidden
_completeCobra command withDisableFlagParsingto pass completion arguments through to the legacy CLI unchanged. - Rewrite generated completion scripts to emit
--shell=<shell>instead of-s<shell>. - Skip update checks and shell-config-leftovers notices for completion requests; add unit and integration tests to cover both short/long forms.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
commands/root.go |
Skips pre/post-run update/notice behaviors for completion requests; registers the new hidden _complete proxy command. |
commands/completion.go |
Rewrites generated completion scripts’ shell option; implements the hidden _complete proxy and completion-request detection. |
commands/completion_test.go |
Unit tests for script shell-option rewriting and for ensuring _complete args reach the command unparsed. |
integration-tests/completion_test.go |
Integration tests validating generated scripts and end-to-end _complete suggestion output for short/long option forms. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Tab completion returns nothing in zsh, bash and fish, out of the box and via
eval "$(upsun completion)". The completion function is registered correctly; the request it makes comes back empty.The generated scripts fetch suggestions from the hidden
_completecommand of the legacy CLI, passing the shell as a glued short option:The Go layer parses these with Cobra before handing them to the legacy CLI. Cobra's root command uses
FParseErrWhitelist{UnknownFlags: true}, which makes pflag walk a glued short option letter by letter (-s,-z,-s,-h). Every supported shell name contains anh, so the bundle always ends with-h, and the root help function rewrites the invocation ashelp _complete …:The completion function silently discards that. The legacy PHP CLI parses the glued form correctly on its own (
php legacy/bin/platform _complete … -szshreturns suggestions), so the Go layer was the only thing at fault.The same applies to the input tokens the scripts pass, which is why fixing only the templates is not enough: completing
upsun ssh --pro<TAB>sends-issh, and thathgets bundled in too.Fix
_completethrough a hidden Cobra command withDisableFlagParsing, so completion requests reach the legacy CLI unchanged. This also repairs completion files users already have installed, and covers input tokens containing anh.--shell=<shell>in the generated scripts, so a request no longer depends on how glued short options are parsed.Verification
Real Tab presses driven through a pty in zsh, bash and fish (Debian container, plus zsh on macOS), for each install method — 27/27 pass with the fix, and the table below shows why the template change alone would not have been sufficient:
upsun env⇥… --for⇥upsun ssh --pro⇥eval "$(upsun completion)"OEM (vendorized) CLIs
Same bug, same fix. Verified with the Akeneo Extension Platform CLI, installed in a container with its own installer (
curl -fsSL https://cli.extension.akeneo.cloud/installer | sh), which downloads the standardupsunrelease binary and points it at the vendorconfig.yamlthrough a wrapper script:env⇥… --for⇥ssh --pro⇥-tags vendorbuild with the Akeneo config embeddedIdentical results in zsh, bash and fish for every row above. OEM users get the fix through the normal release, since the installer pulls the standard release binary.
Tests added:
commands/completion_test.go(script rewrite, and completion arguments reaching the command unparsed) andintegration-tests/completion_test.go(generated scripts, and a real_completerequest in short form, long form, and with an input token containing anh). All fail onmainand pass here.🤖 Generated with Claude Code