Fix zig build lazy -> eager dependency promotion

Before, this had a subtle ordering bug where duplicate
deps that are specified as both lazy and eager in different
parts of the dependency tree end up not getting fetched
depending on the ordering. I modified it to resubmit lazy
deps that were promoted to eager for fetching so that it will
be around for the builds that expect it to be eager downstream
of this.
This commit is contained in:
Timothy Bess 2025-03-09 18:05:11 -04:00 committed by Alex Rønne Petersen
parent 4fd78f9c26
commit 0795e2b2ef
No known key found for this signature in database

View file

@ -735,28 +735,34 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
// calling run(); no need to add it again.
//
// If we add a dep as lazy and then later try to add the same dep as eager,
// eagerness takes precedence and the existing entry is updated.
// eagerness takes precedence and the existing entry is updated and re-scheduled
// for fetching.
for (dep_names, deps) |dep_name, dep| {
var promoted_existing_to_eager = false;
const new_fetch = &new_fetches[new_fetch_index];
const location: Location = switch (dep.location) {
.url => |url| .{ .remote = .{
.url = url,
.hash = h: {
const h = dep.hash orelse break :h null;
const pkg_hash: Package.Hash = .fromSlice(h);
if (h.len == 0) break :h pkg_hash;
const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
if (gop.found_existing) {
if (!dep.lazy) {
gop.value_ptr.*.lazy_status = .eager;
.url => |url| .{
.remote = .{
.url = url,
.hash = h: {
const h = dep.hash orelse break :h null;
const pkg_hash: Package.Hash = .fromSlice(h);
if (h.len == 0) break :h pkg_hash;
const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
if (gop.found_existing) {
if (!dep.lazy and gop.value_ptr.*.lazy_status != .eager) {
gop.value_ptr.*.lazy_status = .eager;
promoted_existing_to_eager = true;
} else {
continue;
}
}
continue;
}
gop.value_ptr.* = new_fetch;
break :h pkg_hash;
gop.value_ptr.* = new_fetch;
break :h pkg_hash;
},
},
} },
},
.path => |rel_path| l: {
// This might produce an invalid path, which is checked for
// at the beginning of run().
@ -764,10 +770,12 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
const pkg_hash = relativePathDigest(new_root, cache_root);
const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
if (gop.found_existing) {
if (!dep.lazy) {
if (!dep.lazy and gop.value_ptr.*.lazy_status != .eager) {
gop.value_ptr.*.lazy_status = .eager;
promoted_existing_to_eager = true;
} else {
continue;
}
continue;
}
gop.value_ptr.* = new_fetch;
break :l .{ .relative_path = new_root };
@ -775,7 +783,9 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
};
prog_names[new_fetch_index] = dep_name;
new_fetch_index += 1;
f.job_queue.all_fetches.appendAssumeCapacity(new_fetch);
if (!promoted_existing_to_eager) {
f.job_queue.all_fetches.appendAssumeCapacity(new_fetch);
}
new_fetch.* = .{
.arena = std.heap.ArenaAllocator.init(gpa),
.location = location,