From 4811899bc5ddee9503c155901db4f4d1ebf9ded1 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 20 Feb 2025 05:46:22 +0100 Subject: [PATCH] Do not drop empty arguments in Bun.spawn (#17269) Co-authored-by: pfg --- src/bun.js/api/bun/subprocess.zig | 4 ---- test/cli/install/bun-create.test.ts | 5 +++-- test/cli/install/bun-publish.test.ts | 8 ++++---- test/cli/install/bun-run.test.ts | 16 +++++++++------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 72d2c9c1c7..3bc5b12ef1 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -1784,10 +1784,6 @@ pub const Subprocess = struct { const arg = try value.toBunString2(globalThis); defer arg.deref(); - // if the string is empty, ignore it, don't add it to the argv - if (arg.isEmpty()) { - continue; - } argv.appendAssumeCapacity(try arg.toOwnedSliceZ(allocator)); } diff --git a/test/cli/install/bun-create.test.ts b/test/cli/install/bun-create.test.ts index 1e8937a014..4744930407 100644 --- a/test/cli/install/bun-create.test.ts +++ b/test/cli/install/bun-create.test.ts @@ -13,13 +13,14 @@ beforeEach(async () => { describe("should not crash", async () => { const args = [ + [bunExe(), "create"], [bunExe(), "create", ""], [bunExe(), "create", "--"], [bunExe(), "create", "--", ""], [bunExe(), "create", "--help"], ]; for (let cmd of args) { - it(JSON.stringify(cmd.slice(1).join(" ")), () => { + it(JSON.stringify(cmd.slice(1)), () => { const { exitCode } = spawnSync({ cmd, cwd: x_dir, @@ -28,7 +29,7 @@ describe("should not crash", async () => { stderr: "inherit", env, }); - expect(exitCode).toBe(cmd.length === 3 && cmd.at(-1) === "" ? 1 : 0); + expect(exitCode).toBe(cmd.length === 2 ? 1 : 0); }); } }); diff --git a/test/cli/install/bun-publish.test.ts b/test/cli/install/bun-publish.test.ts index 0141b078f6..e13148721b 100644 --- a/test/cli/install/bun-publish.test.ts +++ b/test/cli/install/bun-publish.test.ts @@ -592,10 +592,10 @@ postpack: \${fs.existsSync("postpack.txt")}\`)`; }, }; - for (const arg of ["", "--dry-run"]) { - test(`should run in order${arg ? " (--dry-run)" : ""}`, async () => { + for (const arg of [[], ["--dry-run"]]) { + test(`should run in order${arg.length > 0 ? " (--dry-run)" : ""}`, async () => { const { packageDir, packageJson } = await registry.createTestDir(); - const bunfig = await registry.authBunfig("lifecycle" + (arg ? "dry" : "")); + const bunfig = await registry.authBunfig("lifecycle" + (arg.length > 0 ? "dry" : "")); await Promise.all([ rm(join(registry.packagesPath, "publish-pkg-4"), { recursive: true, force: true }), write(packageJson, JSON.stringify(json)), @@ -603,7 +603,7 @@ postpack: \${fs.existsSync("postpack.txt")}\`)`; write(join(packageDir, "bunfig.toml"), bunfig), ]); - const { out, err, exitCode } = await publish(env, packageDir, arg); + const { out, err, exitCode } = await publish(env, packageDir, ...arg); expect(exitCode).toBe(0); const results = await Promise.all([ diff --git a/test/cli/install/bun-run.test.ts b/test/cli/install/bun-run.test.ts index 79379bacdc..10ee354350 100644 --- a/test/cli/install/bun-run.test.ts +++ b/test/cli/install/bun-run.test.ts @@ -38,7 +38,7 @@ for (let withRun of [false, true]) { }`, ); const { stdout, stderr, exitCode } = spawnSync({ - cmd: [bunExe(), withRun ? "run" : "", "."].filter(Boolean), + cmd: [bunExe(), ...(withRun ? ["run"] : []), "."].filter(Boolean), cwd: run_dir, env: bunEnv, }); @@ -59,7 +59,7 @@ for (let withRun of [false, true]) { ); const { stdout, stderr, exitCode } = spawnSync({ - cmd: [bunExe(), withRun ? "run" : "", "."].filter(Boolean), + cmd: [bunExe(), ...(withRun ? ["run"] : []), "."].filter(Boolean), cwd: run_dir, env: bunEnv, }); @@ -84,7 +84,7 @@ for (let withRun of [false, true]) { await writeFile(join(run_dir, "tsconfig.json"), "!!!bad!!!"); const { stdout, stderr, exitCode } = spawnSync({ - cmd: [bunExe(), "--silent", withRun ? "run" : "", "boop"].filter(Boolean), + cmd: [bunExe(), "--silent", ...(withRun ? ["run"] : []), "boop"].filter(Boolean), cwd: run_dir, env: bunEnv, }); @@ -135,7 +135,7 @@ for (let withRun of [false, true]) { it.skipIf(isWindows)("exit signal works", async () => { { const { stdout, stderr, exitCode, signalCode } = spawnSync({ - cmd: [bunExe(), silent ? "--silent" : "", "run", "bash", "-c", "kill -4 $$"].filter(Boolean), + cmd: [bunExe(), ...(silent ? ["--silent"] : []), "run", "bash", "-c", "kill -4 $$"].filter(Boolean), cwd: run_dir, env: bunEnv, }); @@ -152,7 +152,7 @@ for (let withRun of [false, true]) { } { const { stdout, stderr, exitCode, signalCode } = spawnSync({ - cmd: [bunExe(), silent ? "--silent" : "", "run", "bash", "-c", "kill -9 $$"], + cmd: [bunExe(), ...(silent ? ["--silent"] : []), "run", "bash", "-c", "kill -9 $$"], cwd: run_dir, env: bunEnv, }); @@ -204,7 +204,9 @@ logLevel = "debug" const { stdout, stderr, exitCode } = spawnSync({ // TODO: figure out why -c is necessary here. - cmd: [bunExe(), withRun ? "run" : "", "-c=" + join(run_dir, "bunfig.toml"), "./index.js"].filter(Boolean), + cmd: [bunExe(), ...(withRun ? ["run"] : []), "-c=" + join(run_dir, "bunfig.toml"), "./index.js"].filter( + Boolean, + ), cwd: run_dir, env: bunEnv, }); @@ -225,7 +227,7 @@ logLevel = "debug" await writeFile(join(run_dir, "index.ts"), "console.log('Hello, world!');"); const { stdout, stderr, exitCode } = spawnSync({ - cmd: [bunExe(), withRun ? "run" : "", "."].filter(Boolean), + cmd: [bunExe(), ...(withRun ? ["run"] : []), "."].filter(Boolean), cwd: run_dir, env: bunEnv, });