mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-02 03:35:09 +02:00
fix(windows-ci): platform-aware claude-bin test + curate bin/ shebang spawns
Round 3 of windows-free-tests fixes. Round 2 (LF gitattributes + server-node.mjs build) cleared shard 1 entirely (skill-collision-sentinel and tab-isolation green). Shard 2 surfaced two more issues: 1. browse/test/claude-bin.test.ts:50 — the "PATH-resolvable override" test creates a fake binary 'fake-claude-cli' (no extension) and expects Bun.which to find it. On Windows, Bun.which probes PATHEXT extensions (.cmd, .exe, .bat) — a bare-name file is not discoverable. Production behavior is correct; the test was Mac/Linux-shaped. Fix: branch on process.platform. On Windows, write 'fake-claude-cli.cmd' with a Windows batch payload instead of a POSIX shebang script. 2. test/gstack-question-log.test.ts (and 18 sibling tests) — spawn a bash shebang script via spawnSync(BIN, args). Git Bash on Windows can run `bash /path/to/script` but spawnSync invokes CreateProcess directly, which doesn't parse #!/usr/bin/env bash. All these tests are Windows-fragile and can't run as-is. Fix: extend WINDOWS_FRAGILE_PATTERNS with `path.join(.., 'bin', ..)` detector. Curates 19 additional tests (benchmark-cli, brain-sync, builder-profile, explain-level-config, gbrain-*, gstack-question-*, hook-scripts, learnings, plan-tune, review-log, secret-sink-harness, taste-engine, telemetry, timeline, uninstall). Curated Windows subset: 95 → 76 tests (~59% of free suite). Still meaningful Windows coverage. The 52 excluded tests are tracked as a follow-up TODO for full Windows parity (shebang-bin spawns + POSIX file modes + raw /tmp/ etc). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,10 +40,14 @@ describe('claude-bin', () => {
|
||||
|
||||
test('PATH-resolvable override goes through Bun.which (the bug the fork shipped)', () => {
|
||||
// Make a fake binary in a temp dir, point PATH at it, set override to bare command name.
|
||||
// Windows requires the file to have a PATHEXT-listed extension to be discoverable
|
||||
// via Bun.which — without the extension Bun.which returns undefined.
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'claude-bin-test-'));
|
||||
const fakeBin = path.join(tmpDir, 'fake-claude-cli');
|
||||
fs.writeFileSync(fakeBin, '#!/bin/sh\necho fake\n');
|
||||
fs.chmodSync(fakeBin, 0o755);
|
||||
const isWindows = process.platform === 'win32';
|
||||
const fakeBinName = isWindows ? 'fake-claude-cli.cmd' : 'fake-claude-cli';
|
||||
const fakeBin = path.join(tmpDir, fakeBinName);
|
||||
fs.writeFileSync(fakeBin, isWindows ? '@echo fake\r\n' : '#!/bin/sh\necho fake\n');
|
||||
if (!isWindows) fs.chmodSync(fakeBin, 0o755);
|
||||
try {
|
||||
const got = resolveClaudeCommand({
|
||||
PATH: tmpDir,
|
||||
|
||||
@@ -63,6 +63,11 @@ const WINDOWS_FRAGILE_PATTERNS: Array<{ pattern: RegExp; reason: string }> = [
|
||||
{ pattern: /\.mode\s*&\s*0o[0-7]+/, reason: 'POSIX file mode bitmask (mode & 0o600 etc — Windows fakes mode bits)' },
|
||||
{ pattern: /\.endsWith\(['"]\//, reason: 'hardcoded forward-slash path assertion (Windows uses \\\\)' },
|
||||
{ pattern: /['"]\.\/[a-zA-Z][^"']*['"]\)\s*\.\s*toBe\(true\)/, reason: 'forward-slash path comparison' },
|
||||
// Tests that spawn a bash shebang script in bin/ via spawnSync. Git Bash on
|
||||
// Windows can run `bash /path/to/script` but spawnSync(scriptPath, ...)
|
||||
// tries to execute the file directly via CreateProcess, which fails on the
|
||||
// shebang. Catches gstack-question-log.test.ts, gstack-paths.test.ts, etc.
|
||||
{ pattern: /path\.join\([^)]*,\s*['"]bin['"]\s*[,)]/, reason: 'spawns bin/ shebang script (Windows CreateProcess does not parse shebangs)' },
|
||||
];
|
||||
|
||||
export const DEFAULT_SHARD_COUNT = 20;
|
||||
|
||||
Reference in New Issue
Block a user