| ... | @@ -231,6 +231,7 @@ pub fn run(f: *Fetch) RunError!void { | ... | @@ -231,6 +231,7 @@ pub fn run(f: *Fetch) RunError!void { |
| 231 | ); | 231 | ); |
| 232 | f.package_root = try f.parent_package_root.join(arena, sub_path); | 232 | f.package_root = try f.parent_package_root.join(arena, sub_path); |
| 233 | try loadManifest(f, f.package_root); | 233 | try loadManifest(f, f.package_root); |
| | 234 | try checkBuildFileExistence(f); |
| 234 | if (!f.job_queue.recursive) return; | 235 | if (!f.job_queue.recursive) return; |
| 235 | // Package hashes are used as unique identifiers for packages, so | 236 | // Package hashes are used as unique identifiers for packages, so |
| 236 | // we still need one for relative paths. | 237 | // we still need one for relative paths. |
| ... | @@ -279,17 +280,18 @@ pub fn run(f: *Fetch) RunError!void { | ... | @@ -279,17 +280,18 @@ pub fn run(f: *Fetch) RunError!void { |
| 279 | if (cache_root.handle.access(pkg_sub_path, .{})) |_| { | 280 | if (cache_root.handle.access(pkg_sub_path, .{})) |_| { |
| 280 | f.package_root = .{ | 281 | f.package_root = .{ |
| 281 | .root_dir = cache_root, | 282 | .root_dir = cache_root, |
| 282 | .sub_path = pkg_sub_path, | 283 | .sub_path = try arena.dupe(u8, pkg_sub_path), |
| 283 | }; | 284 | }; |
| 284 | try loadManifest(f, f.package_root); | 285 | try loadManifest(f, f.package_root); |
| | 286 | try checkBuildFileExistence(f); |
| 285 | if (!f.job_queue.recursive) return; | 287 | if (!f.job_queue.recursive) return; |
| 286 | return queueJobsForDeps(f, expected_hash); | 288 | return queueJobsForDeps(f, expected_hash); |
| 287 | } else |err| switch (err) { | 289 | } else |err| switch (err) { |
| 288 | error.FileNotFound => {}, | 290 | error.FileNotFound => {}, |
| 289 | else => |e| { | 291 | else => |e| { |
| 290 | try eb.addRootErrorMessage(.{ | 292 | try eb.addRootErrorMessage(.{ |
| 291 | .msg = try eb.printString("unable to open global package cache directory '{s}': {s}", .{ | 293 | .msg = try eb.printString("unable to open global package cache directory '{}{s}': {s}", .{ |
| 292 | try cache_root.join(arena, &.{pkg_sub_path}), @errorName(e), | 294 | cache_root, pkg_sub_path, @errorName(e), |
| 293 | }), | 295 | }), |
| 294 | }); | 296 | }); |
| 295 | return error.FetchFailed; | 297 | return error.FetchFailed; |
| ... | @@ -381,10 +383,13 @@ fn runResource( | ... | @@ -381,10 +383,13 @@ fn runResource( |
| 381 | // by the system. This is done even if the hash is invalid, in case the | 383 | // by the system. This is done even if the hash is invalid, in case the |
| 382 | // package with the different hash is used in the future. | 384 | // package with the different hash is used in the future. |
| 383 | | 385 | |
| 384 | const dest_pkg_sub_path = "p" ++ s ++ Manifest.hexDigest(f.actual_hash); | 386 | f.package_root = .{ |
| 385 | renameTmpIntoCache(cache_root.handle, tmp_dir_sub_path, dest_pkg_sub_path) catch |err| { | 387 | .root_dir = cache_root, |
| | 388 | .sub_path = try arena.dupe(u8, "p" ++ s ++ Manifest.hexDigest(f.actual_hash)), |
| | 389 | }; |
| | 390 | renameTmpIntoCache(cache_root.handle, tmp_dir_sub_path, f.package_root.sub_path) catch |err| { |
| 386 | const src = try cache_root.join(arena, &.{tmp_dir_sub_path}); | 391 | const src = try cache_root.join(arena, &.{tmp_dir_sub_path}); |
| 387 | const dest = try cache_root.join(arena, &.{dest_pkg_sub_path}); | 392 | const dest = try cache_root.join(arena, &.{f.package_root.sub_path}); |
| 388 | try eb.addRootErrorMessage(.{ .msg = try eb.printString( | 393 | try eb.addRootErrorMessage(.{ .msg = try eb.printString( |
| 389 | "unable to rename temporary directory '{s}' into package cache directory '{s}': {s}", | 394 | "unable to rename temporary directory '{s}' into package cache directory '{s}': {s}", |
| 390 | .{ src, dest, @errorName(err) }, | 395 | .{ src, dest, @errorName(err) }, |
| ... | @@ -423,6 +428,25 @@ fn runResource( | ... | @@ -423,6 +428,25 @@ fn runResource( |
| 423 | return queueJobsForDeps(f, actual_hex); | 428 | return queueJobsForDeps(f, actual_hex); |
| 424 | } | 429 | } |
| 425 | | 430 | |
| | 431 | /// `computeHash` gets a free check for the existence of `build.zig`, but when |
| | 432 | /// not computing a hash, we need to do a syscall to check for it. |
| | 433 | fn checkBuildFileExistence(f: *Fetch) RunError!void { |
| | 434 | const eb = &f.error_bundle; |
| | 435 | if (f.package_root.access(Package.build_zig_basename, .{})) |_| { |
| | 436 | f.has_build_zig = true; |
| | 437 | } else |err| switch (err) { |
| | 438 | error.FileNotFound => {}, |
| | 439 | else => |e| { |
| | 440 | try eb.addRootErrorMessage(.{ |
| | 441 | .msg = try eb.printString("unable to access '{}{s}': {s}", .{ |
| | 442 | f.package_root, Package.build_zig_basename, @errorName(e), |
| | 443 | }), |
| | 444 | }); |
| | 445 | return error.FetchFailed; |
| | 446 | }, |
| | 447 | } |
| | 448 | } |
| | 449 | |
| 426 | /// This function populates `f.manifest` or leaves it `null`. | 450 | /// This function populates `f.manifest` or leaves it `null`. |
| 427 | fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void { | 451 | fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void { |
| 428 | const eb = &f.error_bundle; | 452 | const eb = &f.error_bundle; |