Skip to content

Commit 3837865

Browse files
committed
fix(launcher): honor OPENCODEX_BUN_PATH
1 parent 0666b41 commit 3837865

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

bin/ocx.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,22 @@ function bunBinDir() {
292292
// the ~450-byte stub in place, which is NOT executable (ENOEXEC). A size gate
293293
// cleanly distinguishes the stub from a real binary on every platform.
294294
const REAL_BUN_MIN_BYTES = 1_000_000;
295+
const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";
296+
297+
function isRealBunBinary(path) {
298+
try {
299+
return existsSync(path) && statSync(path).size >= REAL_BUN_MIN_BYTES;
300+
} catch {
301+
return false;
302+
}
303+
}
295304

296305
function findBunBinary(bunDir) {
297306
// The npm `bun` package ships the binary as bin/bun.exe on every platform;
298307
// probe bin/bun too for forward compatibility.
299308
for (const name of ["bun.exe", "bun"]) {
300309
const p = join(bunDir, "bin", name);
301-
if (existsSync(p) && statSync(p).size >= REAL_BUN_MIN_BYTES) return p;
310+
if (isRealBunBinary(p)) return p;
302311
}
303312
return null;
304313
}
@@ -317,6 +326,11 @@ function fail(msg) {
317326
}
318327

319328
function resolveBun() {
329+
// Keep direct npm-launcher starts aligned with durable service/shim installs:
330+
// a valid explicit runtime must win even when the bundled dependency exists.
331+
const override = process.env[BUN_OVERRIDE_ENV]?.trim();
332+
if (override && isRealBunBinary(override)) return override;
333+
320334
let bunDir;
321335
try {
322336
bunDir = bunBinDir();

tests/ocx-launcher-source.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,21 @@ describe("ocx.mjs npm launcher (source invariants)", () => {
2222
expect(source).toContain('if (explicit === "preview" || explicit === "latest") return explicit;');
2323
expect(source).not.toMatch(/if \(tagIndex !== -1 && process\.argv\[tagIndex \+ 1\]\) return process\.argv/);
2424
});
25+
26+
test("valid Bun overrides are selected before the bundled runtime", () => {
27+
expect(source).toContain('const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";');
28+
expect(source).toContain("if (override && isRealBunBinary(override)) return override;");
29+
30+
const resolveStart = source.indexOf("function resolveBun() {");
31+
const overrideCheck = source.indexOf("process.env[BUN_OVERRIDE_ENV]?.trim()", resolveStart);
32+
const bundledLookup = source.indexOf("bunDir = bunBinDir()", resolveStart);
33+
expect(resolveStart).toBeGreaterThanOrEqual(0);
34+
expect(overrideCheck).toBeGreaterThan(resolveStart);
35+
expect(bundledLookup).toBeGreaterThan(overrideCheck);
36+
});
37+
38+
test("invalid Bun overrides fall back without throwing", () => {
39+
expect(source).toContain("function isRealBunBinary(path) {");
40+
expect(source).toMatch(/function isRealBunBinary\(path\) \{[\s\S]*?try \{[\s\S]*?statSync\(path\)[\s\S]*?catch \{[\s\S]*?return false;/);
41+
});
2542
});

0 commit comments

Comments
 (0)