commit e661e78256e195e23ef7ffded47c2256d0a7620f (tree)
parent 3d33735d73de269278fb87d2c9ae8fb7d83977be
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 6 Feb 2026 13:21:13 -0800
store the Manifest in the fork set
Diffstat:
4 files changed, 51 insertions(+), 20 deletions(-)
diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig
@@ -1657,7 +1657,7 @@ fn printUsage(b: *std.Build, w: *Writer) !void {
\\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit
\\ needed (Default) Lazy dependencies are fetched as needed
\\ all Lazy dependencies are always fetched
- \\ --fork=[path] Override one or more packages from dependency tree
+ \\ --fork=[path] Override one or more projects from dependency tree
\\
\\Advanced Options:
\\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
diff --git a/src/Package.zig b/src/Package.zig
@@ -174,6 +174,15 @@ pub const ProjectId = struct {
.fingerprint_id = fingerprint_id,
};
}
+
+ pub fn eql(a: *const ProjectId, b: *const ProjectId) bool {
+ return a.fingerprint_id == b.fingerprint_id and std.mem.eql(u8, &a.padded_name, &b.padded_name);
+ }
+
+ pub fn hash(a: *const ProjectId) u64 {
+ const x: u64 = @bitCast(a.padded_name[0..8].*);
+ return std.hash.int(x | a.fingerprint_id);
+ }
};
pub const MultihashFunction = enum(u16) {
diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig
@@ -154,7 +154,26 @@ pub const JobQueue = struct {
};
pub const Table = std.AutoArrayHashMapUnmanaged(Package.Hash, *Fetch);
pub const UnlazySet = std.AutoArrayHashMapUnmanaged(Package.Hash, void);
- pub const ForkSet = std.AutoArrayHashMapUnmanaged(Package.ProjectId, Cache.Path);
+ pub const ForkSet = std.ArrayHashMapUnmanaged(Fork, void, Fork.Context, false);
+
+ pub const Fork = struct {
+ path: Cache.Path,
+ manifest_ast: std.zig.Ast,
+ manifest: Package.Manifest,
+
+ pub const Context = struct {
+ pub fn hash(_: @This(), a: Fork) u32 {
+ const project_id: Package.ProjectId = .init(a.manifest.name, a.manifest.id);
+ return @truncate(project_id.hash());
+ }
+
+ pub fn eql(_: @This(), a: Fork, b: Fork, _: usize) bool {
+ const a_project_id: Package.ProjectId = .init(a.manifest.name, a.manifest.id);
+ const b_project_id: Package.ProjectId = .init(b.manifest.name, b.manifest.id);
+ return a_project_id.eql(&b_project_id);
+ }
+ };
+ };
pub fn deinit(jq: *JobQueue) void {
const io = jq.io;
diff --git a/src/main.zig b/src/main.zig
@@ -5003,11 +5003,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
});
} else if (mem.cutPrefix(u8, arg, "--fork=")) |sub_arg| {
try forks.append(arena, .{
- .project_id = undefined,
+ .manifest_ast = undefined,
+ .manifest = undefined,
+ .error_bundle = undefined,
.path = .{
.root_dir = .cwd(),
.sub_path = sub_arg,
},
+ .failed = false,
});
} else if (mem.eql(u8, arg, "--system")) {
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,
try group.await(io);
for (forks.items) |*fork| {
- const project_id = fork.project_id catch |err| switch (err) {
- error.AlreadyReported => process.exit(1),
- };
- try fork_set.put(arena, project_id, fork.path);
+ if (fork.failed) process.exit(1);
+ try fork_set.put(arena, .{
+ .path = fork.path,
+ .manifest_ast = fork.manifest_ast,
+ .manifest = fork.manifest,
+ }, {});
}
}
@@ -5548,21 +5553,24 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
const Fork = struct {
path: Path,
- project_id: error{AlreadyReported}!Package.ProjectId,
+ manifest_ast: std.zig.Ast,
+ manifest: Package.Manifest,
+ error_bundle: std.zig.ErrorBundle.Wip,
+ failed: bool,
};
fn loadFork(io: Io, gpa: Allocator, fork: *Fork, color: Color) Io.Cancelable!void {
- fork.project_id = loadForkFallible(io, gpa, fork, color) catch |err| switch (err) {
+ loadForkFallible(io, gpa, fork, color) catch |err| switch (err) {
error.Canceled => |e| return e,
- error.AlreadyReported => |e| e,
- else => |e| e: {
+ error.AlreadyReported => fork.failed = true,
+ else => |e| {
std.log.err("failed to load fork at {f}: {t}", .{ fork.path, e });
- break :e error.AlreadyReported;
+ fork.failed = true;
},
};
}
-fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.ProjectId {
+fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !void {
var arena_instance = std.heap.ArenaAllocator.init(gpa);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
@@ -5573,16 +5581,13 @@ fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.
const manifest_path = try fork.path.join(arena, Package.Manifest.basename);
- var manifest_ast: std.zig.Ast = undefined;
- var manifest: Package.Manifest = undefined;
-
Package.Manifest.load(
io,
arena,
manifest_path,
- &manifest_ast,
+ &fork.manifest_ast,
&error_bundle,
- &manifest,
+ &fork.manifest,
true,
) catch |err| switch (err) {
error.Canceled => |e| return e,
@@ -5597,8 +5602,6 @@ fn loadForkFallible(io: Io, gpa: Allocator, fork: *Fork, color: Color) !Package.
return error.AlreadyReported;
},
};
-
- return .init(manifest.name, manifest.id);
}
const JitCmdOptions = struct {