diff --git a/src/install/migration.zig b/src/install/migration.zig index 888cac4d2c..7659779984 100644 --- a/src/install/migration.zig +++ b/src/install/migration.zig @@ -30,7 +30,7 @@ pub fn detectAndLoadOtherLockfile( .step = .migrating, .value = err, .lockfile_path = "package-lock.json", - .format = .binary, + .format = .text, } }; }; @@ -54,7 +54,7 @@ pub fn detectAndLoadOtherLockfile( .step = .migrating, .value = err, .lockfile_path = "yarn.lock", - .format = .binary, + .format = .text, } }; }; @@ -126,7 +126,7 @@ pub fn detectAndLoadOtherLockfile( .step = .migrating, .value = err, .lockfile_path = "pnpm-lock.yaml", - .format = .binary, + .format = .text, } }; }; @@ -1089,7 +1089,7 @@ pub fn migrateNPMLockfile( .migrated = .npm, .loaded_from_binary_lockfile = false, .serializer_result = .{}, - .format = .binary, + .format = .text, }, }; } diff --git a/src/install/yarn.zig b/src/install/yarn.zig index 6baaf5e9cb..fbf9e66737 100644 --- a/src/install/yarn.zig +++ b/src/install/yarn.zig @@ -1684,7 +1684,7 @@ pub fn migrateYarnLockfile( .migrated = .yarn, .loaded_from_binary_lockfile = false, .serializer_result = .{}, - .format = .binary, + .format = .text, } }; return result; diff --git a/test/regression/issue/migration-lockfile-format.test.ts b/test/regression/issue/migration-lockfile-format.test.ts new file mode 100644 index 0000000000..db4c1ac95d --- /dev/null +++ b/test/regression/issue/migration-lockfile-format.test.ts @@ -0,0 +1,132 @@ +import { expect, test } from "bun:test"; +import { existsSync } from "fs"; +import { bunEnv, bunExe, tempDir } from "harness"; +import { join } from "path"; + +test("failing to migrate pnpm-lock.yaml should create bun.lock not bun.lockb", async () => { + using dir = tempDir("pnpm-migration-format", { + "package.json": JSON.stringify({ + name: "test", + version: "1.0.0", + dependencies: { + "is-even": "1.0.0", + }, + }), + // Create an invalid pnpm-lock.yaml that will fail to migrate + "pnpm-lock.yaml": `lockfileVersion: '9.0' +importers: + .: + dependencies: + is-even: + specifier: 1.0.0 + version: 1.0.0 +packages: + /is-even@1.0.0: + resolution: {integrity: sha512-invalid-integrity} + engines: {node: '>=0.10.0'} +`, + }); + + const result = await Bun.spawn({ + cmd: [bunExe(), "install"], + cwd: String(dir), + env: bunEnv, + stderr: "pipe", + stdout: "pipe", + }).exited; + + // After failed migration, bun.lock should exist (not bun.lockb) + const bunLockPath = join(String(dir), "bun.lock"); + const bunLockbPath = join(String(dir), "bun.lockb"); + + expect(existsSync(bunLockPath)).toBe(true); + expect(existsSync(bunLockbPath)).toBe(false); +}); + +// Note: This test verifies the fix but may pass even if migration succeeds +// The key fix is that error paths return .format = .text instead of .format = .binary +test("after yarn.lock exists, bun install should create bun.lock not bun.lockb", async () => { + using dir = tempDir("yarn-migration-format", { + "package.json": JSON.stringify({ + name: "test", + version: "1.0.0", + dependencies: { + "is-number": "7.0.0", + }, + }), + // Create a valid yarn.lock to ensure migration happens + "yarn.lock": `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +is-number@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +`, + }); + + await Bun.spawn({ + cmd: [bunExe(), "install"], + cwd: String(dir), + env: bunEnv, + stderr: "pipe", + stdout: "pipe", + }).exited; + + // After migration, bun.lock should exist (not bun.lockb) + const bunLockPath = join(String(dir), "bun.lock"); + const bunLockbPath = join(String(dir), "bun.lockb"); + + expect(existsSync(bunLockPath)).toBe(true); + expect(existsSync(bunLockbPath)).toBe(false); +}); + +test("successful migration from package-lock.json should create bun.lock not bun.lockb", async () => { + using dir = tempDir("npm-migration-format", { + "package.json": JSON.stringify({ + name: "test", + version: "1.0.0", + dependencies: { + "is-number": "7.0.0", + }, + }), + "package-lock.json": JSON.stringify({ + name: "test", + version: "1.0.0", + lockfileVersion: 3, + requires: true, + packages: { + "": { + name: "test", + version: "1.0.0", + dependencies: { + "is-number": "7.0.0", + }, + }, + "node_modules/is-number": { + version: "7.0.0", + resolved: "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + integrity: "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + engines: { + node: ">=0.12.0", + }, + }, + }, + }), + }); + + const result = await Bun.spawn({ + cmd: [bunExe(), "install"], + cwd: String(dir), + env: bunEnv, + stderr: "pipe", + stdout: "pipe", + }).exited; + + // After successful migration, bun.lock should exist (not bun.lockb) + const bunLockPath = join(String(dir), "bun.lock"); + const bunLockbPath = join(String(dir), "bun.lockb"); + + expect(existsSync(bunLockPath)).toBe(true); + expect(existsSync(bunLockbPath)).toBe(false); +});