authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-06 13:21:13-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-06 13:21:13-08:00
loge661e78256e195e23ef7ffded47c2256d0a7620f
tree07f284296948432cae883e25785162de67537357
parent3d33735d73de269278fb87d2c9ae8fb7d83977be

store the Manifest in the fork set


4 files changed, 51 insertions(+), 20 deletions(-)

lib/compiler/build_runner.zig+1-1
......@@ -1657,7 +1657,7 @@ fn printUsage(b: *std.Build, w: *Writer) !void {
16571657 \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit
16581658 \\ needed (Default) Lazy dependencies are fetched as needed
16591659 \\ all Lazy dependencies are always fetched
1660 \\ --fork=[path] Override one or more packages from dependency tree
1660 \\ --fork=[path] Override one or more projects from dependency tree
16611661 \\
16621662 \\Advanced Options:
16631663 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
src/Package.zig+9
......@@ -174,6 +174,15 @@ pub const ProjectId = struct {
174174 .fingerprint_id = fingerprint_id,
175175 };
176176 }
177
178 pub fn eql(a: *const ProjectId, b: *const ProjectId) bool {
179 return a.fingerprint_id == b.fingerprint_id and std.mem.eql(u8, &a.padded_name, &b.padded_name);
180 }
181
182 pub fn hash(a: *const ProjectId) u64 {
183 const x: u64 = @bitCast(a.padded_name[0..8].*);
184 return std.hash.int(x | a.fingerprint_id);
185 }
177186};
178187
179188pub const MultihashFunction = enum(u16) {
src/Package/Fetch.zig+20-1
......@@ -154,7 +154,26 @@ pub const JobQueue = struct {
154154 };
155155 pub const Table = std.AutoArrayHashMapUnmanaged(Package.Hash, *Fetch);
156156 pub const UnlazySet = std.AutoArrayHashMapUnmanaged(Package.Hash, void);
157 pub const ForkSet = std.AutoArrayHashMapUnmanaged(Package.ProjectId, Cache.Path);
157 pub const ForkSet = std.ArrayHashMapUnmanaged(Fork, void, Fork.Context, false);
158
159 pub const Fork = struct {
160 path: Cache.Path,
161 manifest_ast: std.zig.Ast,
162 manifest: Package.Manifest,
163
164 pub const Context = struct {
165 pub fn hash(_: @This(), a: Fork) u32 {
166 const project_id: Package.ProjectId = .init(a.manifest.name, a.manifest.id);
167 return @truncate(project_id.hash());
168 }
169
170 pub fn eql(_: @This(), a: Fork, b: Fork, _: usize) bool {
171 const a_project_id: Package.ProjectId = .init(a.manifest.name, a.manifest.id);
172 const b_project_id: Package.ProjectId = .init(b.manifest.name, b.manifest.id);
173 return a_project_id.eql(&b_project_id);
174 }
175 };
176 };
158177
159178 pub fn deinit(jq: *JobQueue) void {
160179 const io = jq.io;
src/main.zig+21-18
......@@ -5003,11 +5003,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
50035003 });
50045004 } else if (mem.cutPrefix(u8, arg, "--fork=")) |sub_arg| {
50055005 try forks.append(arena, .{
5006 .project_id = undefined,
5006 .manifest_ast = undefined,
5007 .manifest = undefined,
5008 .error_bundle = undefined,
50075009 .path = .{
50085010 .root_dir = .cwd(),
50095011 .sub_path = sub_arg,
50105012 },
5013 .failed = false,
50115014 });
50125015 } else if (mem.eql(u8, arg, "--system")) {
50135016 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
......@@ -5204,10 +5207,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
52045207 try group.await(io);
52055208
52065209 for (forks.items) |*fork| {
5207 const project_id = fork.project_id catch |err| switch (err) {
5208 error.AlreadyReported => process.exit(1),
5209 };
5210 try fork_set.put(arena, project_id, fork.path);
5210 if (fork.failed) process.exit(1);
5211 try fork_set.put(arena, .{
5212 .path = fork.path,
5213 .manifest_ast = fork.manifest_ast,
5214 .manifest = fork.manifest,
5215 }, {});
52115216 }
52125217 }
52135218
......@@ -5548,21 +5553,24 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
55485553
55495554const Fork = struct {
55505555 path: Path,
5551 project_id: error{AlreadyReported}!Package.ProjectId,
5556 manifest_ast: std.zig.Ast,
5557 manifest: Package.Manifest,
5558 error_bundle: std.zig.ErrorBundle.Wip,
5559 failed: bool,
55525560};
55535561
55545562fn loadFork(io: Io, gpa: Allocator, fork: *Fork, color: Color) Io.Cancelable!void {
5555 fork.project_id = loadForkFallible(io, gpa, fork, color) catch |err| switch (err) {
5563 loadForkFallible(io, gpa, fork, color) catch |err| switch (err) {
55565564 error.Canceled => |e| return e,
5557 error.AlreadyReported => |e| e,
5558 else => |e| e: {
5565 error.AlreadyReported => fork.failed = true,
5566 else => |e| {
55595567 std.log.err("failed to load fork at {f}: {t}", .{ fork.path, e });
5560 break :e error.AlreadyReported;
5568 fork.failed = true;
55615569 },
55625570 };
55635571}
55645572
5565fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.ProjectId {
5573fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !void {
55665574 var arena_instance = std.heap.ArenaAllocator.init(gpa);
55675575 defer arena_instance.deinit();
55685576 const arena = arena_instance.allocator();
......@@ -5573,16 +5581,13 @@ fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.
55735581
55745582 const manifest_path = try fork.path.join(arena, Package.Manifest.basename);
55755583
5576 var manifest_ast: std.zig.Ast = undefined;
5577 var manifest: Package.Manifest = undefined;
5578
55795584 Package.Manifest.load(
55805585 io,
55815586 arena,
55825587 manifest_path,
5583 &manifest_ast,
5588 &fork.manifest_ast,
55845589 &error_bundle,
5585 &manifest,
5590 &fork.manifest,
55865591 true,
55875592 ) catch |err| switch (err) {
55885593 error.Canceled => |e| return e,
......@@ -5597,8 +5602,6 @@ fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.
55975602 return error.AlreadyReported;
55985603 },
55995604 };
5600
5601 return .init(manifest.name, manifest.id);
56025605}
56035606
56045607const JitCmdOptions = struct {