fix(cli): prevent --version/--help interception in standalone executables with compile-exec-argv (#26083)

## Summary

Fixes https://github.com/oven-sh/bun/issues/26082

- Fixes a bug where standalone executables compiled with
`--compile-exec-argv` would intercept `--version`, `-v`, `--help`, and
`-h` flags before user code could handle them
- CLI applications using libraries like `commander` can now properly
implement their own version and help commands

## Root Cause

When `--compile-exec-argv` is used, `Command.init` was being called with
`.AutoCommand`, which parses ALL arguments (including user arguments).
The `Arguments.parse` function intercepts `--version`/`--help` flags for
`AutoCommand`, preventing them from reaching user code.

## Fix

Temporarily set `bun.argv` to only include the executable name +
embedded exec argv options when calling `Command.init`. This ensures:
1. Bun's embedded options (like `--smol`, `--use-system-ca`) are
properly parsed
2. User arguments (including `--version`/`--help`) are NOT intercepted
by Bun's parser
3. User arguments are properly passed through to user code

## Test plan

- [x] Added tests for `--version`, `-v`, `--help`, and `-h` flags in
`compile-argv.test.ts`
- [x] Verified tests fail with `USE_SYSTEM_BUN=1` (proving the bug
exists)
- [x] Verified tests pass with debug build
- [x] Verified existing compile-argv tests still pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
robobun
2026-01-14 13:10:53 -08:00
committed by GitHub
parent 5a71ead8a2
commit 6e6896510a
2 changed files with 117 additions and 3 deletions

View File

@@ -175,4 +175,105 @@ describe("bundler", () => {
stdout: /SUCCESS: user arguments properly passed with exec argv present/,
},
});
// Test that --version and --help flags are passed through to user code (issue #26082)
// When compile-exec-argv is used, user flags like --version should NOT be intercepted by Bun
itBundled("compile/CompileExecArgvVersionHelpPassthrough", {
compile: {
execArgv: ["--smol"],
},
backend: "cli",
files: {
"/entry.ts": /* js */ `
// Test that --version and --help are passed through to user code, not intercepted by Bun
const args = process.argv.slice(2);
console.log("User args:", JSON.stringify(args));
if (args.includes("--version")) {
console.log("APP_VERSION:1.0.0");
} else if (args.includes("-v")) {
console.log("APP_VERSION:1.0.0");
} else if (args.includes("--help")) {
console.log("APP_HELP:This is my app help");
} else if (args.includes("-h")) {
console.log("APP_HELP:This is my app help");
} else {
console.log("NO_FLAG_MATCHED");
}
`,
},
run: {
args: ["--version"],
stdout: /APP_VERSION:1\.0\.0/,
},
});
// Test with -v short flag
itBundled("compile/CompileExecArgvShortVersionPassthrough", {
compile: {
execArgv: ["--smol"],
},
backend: "cli",
files: {
"/entry.ts": /* js */ `
const args = process.argv.slice(2);
if (args.includes("-v")) {
console.log("APP_VERSION:1.0.0");
} else {
console.log("FAIL: -v not found in args:", args);
process.exit(1);
}
`,
},
run: {
args: ["-v"],
stdout: /APP_VERSION:1\.0\.0/,
},
});
// Test with --help flag
itBundled("compile/CompileExecArgvHelpPassthrough", {
compile: {
execArgv: ["--smol"],
},
backend: "cli",
files: {
"/entry.ts": /* js */ `
const args = process.argv.slice(2);
if (args.includes("--help")) {
console.log("APP_HELP:my custom help");
} else {
console.log("FAIL: --help not found in args:", args);
process.exit(1);
}
`,
},
run: {
args: ["--help"],
stdout: /APP_HELP:my custom help/,
},
});
// Test with -h short flag
itBundled("compile/CompileExecArgvShortHelpPassthrough", {
compile: {
execArgv: ["--smol"],
},
backend: "cli",
files: {
"/entry.ts": /* js */ `
const args = process.argv.slice(2);
if (args.includes("-h")) {
console.log("APP_HELP:my custom help");
} else {
console.log("FAIL: -h not found in args:", args);
process.exit(1);
}
`,
},
run: {
args: ["-h"],
stdout: /APP_HELP:my custom help/,
},
});
});