Skip to content

Commit

Permalink
Fix lifecycle scripts not running on reinstallation (oven-sh#6376)
Browse files Browse the repository at this point in the history
* Include trusted dependencies in lockfile

* Add a remote dependency to lifecycle script test
  • Loading branch information
Arden144 authored Oct 11, 2023
1 parent c2c3b0d commit 39446eb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
38 changes: 38 additions & 0 deletions src/install/lockfile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4221,6 +4221,7 @@ pub const Serializer = struct {
const header_bytes: string = "#!/usr/bin/env bun\n" ++ version;

const has_workspace_package_ids_tag: u64 = @bitCast([_]u8{ 'w', 'O', 'r', 'K', 's', 'P', 'a', 'C' });
const has_trusted_dependencies_tag: u64 = @bitCast([_]u8{ 't', 'R', 'u', 'S', 't', 'E', 'D', 'd' });

pub fn save(this: *Lockfile, comptime StreamType: type, stream: StreamType) !void {
var old_package_list = this.packages;
Expand Down Expand Up @@ -4282,6 +4283,19 @@ pub const Serializer = struct {
);
}

if (this.trusted_dependencies.count() > 0) {
try writer.writeAll(std.mem.asBytes(&has_trusted_dependencies_tag));

try Lockfile.Buffers.writeArray(
StreamType,
stream,
@TypeOf(&writer),
&writer,
[]u32,
this.trusted_dependencies.keys(),
);
}

const end = try stream.getPos();

try writer.writeAll(&alignment_bytes_to_repeat_buffer);
Expand Down Expand Up @@ -4393,6 +4407,30 @@ pub const Serializer = struct {
}
}

{
const remaining_in_buffer = total_buffer_size -| stream.pos;

if (remaining_in_buffer > 8 and total_buffer_size <= stream.buffer.len) {
const next_num = try reader.readIntLittle(u64);
if (next_num == has_trusted_dependencies_tag) {
var trusted_dependencies_hashes = try Lockfile.Buffers.readArray(
stream,
allocator,
std.ArrayListUnmanaged(u32),
);
defer trusted_dependencies_hashes.deinit(allocator);

try lockfile.trusted_dependencies.ensureTotalCapacity(allocator, trusted_dependencies_hashes.items.len);

lockfile.trusted_dependencies.entries.len = trusted_dependencies_hashes.items.len;
@memcpy(lockfile.trusted_dependencies.keys(), trusted_dependencies_hashes.items);
try lockfile.trusted_dependencies.reIndex(allocator);
} else {
stream.pos -= 8;
}
}
}

lockfile.scratch = Lockfile.Scratch.init(allocator);
lockfile.package_index = PackageIndex.Map.initContext(allocator, .{});
lockfile.string_pool = StringPool.initContext(allocator, .{});
Expand Down
30 changes: 21 additions & 9 deletions test/cli/install/bun-install.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,8 @@ it("should handle life-cycle scripts within workspaces", async () => {
});

it("should handle life-cycle scripts during re-installation", async () => {
const urls: string[] = [];
setHandler(dummyRegistry(urls));
await writeFile(
join(package_dir, "package.json"),
JSON.stringify({
Expand All @@ -828,6 +830,10 @@ it("should handle life-cycle scripts during re-installation", async () => {
scripts: {
install: [bunExe(), "index.js"].join(" "),
},
dependencies: {
qux: "^0.0",
},
trustedDependencies: ["qux"],
workspaces: ["bar"],
}),
);
Expand Down Expand Up @@ -865,13 +871,15 @@ it("should handle life-cycle scripts during re-installation", async () => {
expect(out1.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"[scripts:run] Bar",
" + Bar@workspace:bar",
" + qux@0.0.2",
"[scripts:run] Foo",
"[scripts:run] Qux",
"",
" 1 package installed",
" 2 packages installed",
]);
expect(await exited1).toBe(0);
expect(requested).toBe(0);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "Bar"]);
expect(requested).toBe(2);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "Bar", "qux"]);
expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
await access(join(package_dir, "bun.lockb"));
// Perform `bun install` again but with lockfile from before
Expand All @@ -897,13 +905,15 @@ it("should handle life-cycle scripts during re-installation", async () => {
expect(out2.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"[scripts:run] Bar",
" + Bar@workspace:bar",
" + qux@0.0.2",
"[scripts:run] Foo",
"[scripts:run] Qux",
"",
" 1 package installed",
" 2 packages installed",
]);
expect(await exited2).toBe(0);
expect(requested).toBe(0);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual(["Bar"]);
expect(requested).toBe(3);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "Bar", "qux"]);
expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
await access(join(package_dir, "bun.lockb"));
// Perform `bun install --production` with lockfile from before
Expand All @@ -929,13 +939,15 @@ it("should handle life-cycle scripts during re-installation", async () => {
expect(out3.replace(/\s*\[[0-9\.]+m?s\]\s*$/, "").split(/\r?\n/)).toEqual([
"[scripts:run] Bar",
" + Bar@workspace:bar",
" + qux@0.0.2",
"[scripts:run] Foo",
"[scripts:run] Qux",
"",
" 1 package installed",
" 2 packages installed",
]);
expect(await exited3).toBe(0);
expect(requested).toBe(0);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual(["Bar"]);
expect(requested).toBe(4);
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "Bar", "qux"]);
expect(await readlink(join(package_dir, "node_modules", "Bar"))).toBe(join("..", "bar"));
await access(join(package_dir, "bun.lockb"));
});
Expand Down
Binary file added test/cli/install/qux-0.0.2.tgz
Binary file not shown.

0 comments on commit 39446eb

Please sign in to comment.