-
Notifications
You must be signed in to change notification settings - Fork 5k
completions: fix 4 correctness bugs in zsh/bash/fish scripts #36515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
cff24b2
completions: fix 4 correctness bugs in zsh/bash/fish scripts
robobun eb60d65
[autofix.ci] apply automated fixes
autofix-ci[bot] e4b3ff2
bash: make the script-filter block unconditional instead of dropping …
robobun 9df10cd
[autofix.ci] apply automated fixes
autofix-ci[bot] 26844d1
test: clear HOME/BUN_INSTALL so bun completions cannot write outside …
robobun 205ef24
test: gate functional bash probe on bash>=4; assert fish flag/desc po…
robobun 66b7669
test: skip bash -n test when bash is absent from PATH
robobun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| import { describe, expect, test } from "bun:test"; | ||
| import { bunEnv, bunExe, isWindows, tempDir } from "harness"; | ||
|
|
||
| // `bun completions` writes the embedded completion script for the shell named | ||
| // by $SHELL to stdout when stdout is not a TTY. This lets us assert on the | ||
| // bytes that ship inside the binary (from completions/bun.{zsh,bash,fish}). | ||
| async function emitCompletions(shell: "zsh" | "bash" | "fish"): Promise<string> { | ||
| await using proc = Bun.spawn({ | ||
| cmd: [bunExe(), "completions"], | ||
| env: { ...bunEnv, SHELL: `/bin/${shell}`, IS_BUN_AUTO_UPDATE: undefined }, | ||
| stdout: "pipe", | ||
| stderr: "pipe", | ||
| }); | ||
|
Check failure on line 13 in test/cli/shell-completion-scripts.test.ts
|
||
|
robobun marked this conversation as resolved.
|
||
| const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); | ||
| expect(stderr).not.toContain("error"); | ||
| expect(exitCode).toBe(0); | ||
| return stdout; | ||
| } | ||
|
|
||
| // `bun completions` is a no-op on Windows (PowerShell completions are not | ||
| // implemented), so these tests can only run on POSIX. | ||
| describe.skipIf(isWindows)("shell completion scripts", () => { | ||
|
robobun marked this conversation as resolved.
|
||
| test("zsh: -i optspec has closing bracket inside the quote", async () => { | ||
| // #31665: the line was `...=fallback'] \` (bracket outside the quote), | ||
| // which zsh _arguments sees as a stray literal `]` argument. | ||
| const script = await emitCompletions("zsh"); | ||
| expect(script).toContain("--install=fallback]' \\"); | ||
| expect(script).not.toContain("--install=fallback'] \\"); | ||
| }); | ||
|
|
||
| test("zsh: _bun_add_param_package_completion prints history instead of executing it", async () => { | ||
| // #34062: `$($inexact | grep ...)` runs the first history entry as a | ||
| // command. It should be `$(print -l -- $inexact | grep ...)`. | ||
| const script = await emitCompletions("zsh"); | ||
| expect(script).toContain("print -l -- $inexact | grep"); | ||
| expect(script).not.toContain("($($inexact | grep"); | ||
| }); | ||
|
|
||
| test("bash: no reference to undeclared re_comp_word_script", async () => { | ||
| // #28744: ${re_comp_word_script} was never defined; the OR arm expanded | ||
| // to `=~ ` which is an empty pattern. | ||
| const script = await emitCompletions("bash"); | ||
| expect(script).not.toContain("re_comp_word_script"); | ||
| }); | ||
|
|
||
| test("bash: script passes bash -n", async () => { | ||
| const script = await emitCompletions("bash"); | ||
| using dir = tempDir("bun-bash-completion", { "bun.bash": script }); | ||
| await using proc = Bun.spawn({ | ||
| cmd: ["bash", "-n", "bun.bash"], | ||
| cwd: String(dir), | ||
| env: bunEnv, | ||
| stdout: "pipe", | ||
| stderr: "pipe", | ||
| }); | ||
| const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); | ||
| expect(stderr).toBe(""); | ||
| expect(stdout).toBe(""); | ||
| expect(exitCode).toBe(0); | ||
| }); | ||
|
|
||
| test("fish: install boolean flags include frozen-lockfile and descriptions line up", async () => { | ||
| // #29364: frozen-lockfile was missing and dry-run's description was wrong. | ||
| const script = await emitCompletions("fish"); | ||
| const flagsLine = script.split("\n").find(l => l.startsWith("set -l bun_install_boolean_flags ")); | ||
| const descLine = script.split("\n").find(l => l.startsWith("set -l bun_install_boolean_flags_descriptions ")); | ||
| expect(flagsLine).toBeDefined(); | ||
| expect(descLine).toBeDefined(); | ||
|
|
||
| const flags = flagsLine!.replace("set -l bun_install_boolean_flags ", "").trim().split(/\s+/); | ||
| // Descriptions are quoted with "..." and separated by a single space. | ||
| const descs = [...descLine!.matchAll(/"[^"]*"/g)].map(m => m[0]); | ||
|
|
||
| expect(flags).toContain("frozen-lockfile"); | ||
| // The two parallel lists must stay in lockstep or every flag after the | ||
| // first mismatch gets the wrong help text. | ||
| expect(descs.length).toBe(flags.length); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.