| ... | ... | @@ -47,10 +47,16 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.key_length); |
| 47 | 47 | pub const File = struct { |
| 48 | 48 | path: ?[]const u8, |
| 49 | 49 | max_file_size: ?usize, |
| 50 | | stat: fs.File.Stat, |
| 50 | stat: Stat, |
| 51 | 51 | bin_digest: BinDigest, |
| 52 | 52 | contents: ?[]const u8, |
| 53 | 53 | |
| 54 | pub const Stat = struct { |
| 55 | inode: fs.File.INode, |
| 56 | size: u64, |
| 57 | mtime: i128, |
| 58 | }; |
| 59 | |
| 54 | 60 | pub fn deinit(self: *File, allocator: Allocator) void { |
| 55 | 61 | if (self.path) |owned_slice| { |
| 56 | 62 | allocator.free(owned_slice); |
| ... | ... | @@ -424,7 +430,11 @@ pub const Manifest = struct { |
| 424 | 430 | if (!size_match or !mtime_match or !inode_match) { |
| 425 | 431 | self.manifest_dirty = true; |
| 426 | 432 | |
| 427 | | cache_hash_file.stat = actual_stat; |
| 433 | cache_hash_file.stat = .{ |
| 434 | .size = actual_stat.size, |
| 435 | .mtime = actual_stat.mtime, |
| 436 | .inode = actual_stat.inode, |
| 437 | }; |
| 428 | 438 | |
| 429 | 439 | if (self.isProblematicTimestamp(cache_hash_file.stat.mtime)) { |
| 430 | 440 | // The actual file has an unreliable timestamp, force it to be hashed |
| ... | ... | @@ -530,7 +540,12 @@ pub const Manifest = struct { |
| 530 | 540 | const file = try fs.cwd().openFile(ch_file.path.?, .{}); |
| 531 | 541 | defer file.close(); |
| 532 | 542 | |
| 533 | | ch_file.stat = try file.stat(); |
| 543 | const actual_stat = try file.stat(); |
| 544 | ch_file.stat = .{ |
| 545 | .size = actual_stat.size, |
| 546 | .mtime = actual_stat.mtime, |
| 547 | .inode = actual_stat.inode, |
| 548 | }; |
| 534 | 549 | |
| 535 | 550 | if (self.isProblematicTimestamp(ch_file.stat.mtime)) { |
| 536 | 551 | // The actual file has an unreliable timestamp, force it to be hashed |
| ... | ... | @@ -615,6 +630,42 @@ pub const Manifest = struct { |
| 615 | 630 | try self.populateFileHash(new_ch_file); |
| 616 | 631 | } |
| 617 | 632 | |
| 633 | /// Like `addFilePost` but when the file contents have already been loaded from disk. |
| 634 | /// On success, cache takes ownership of `resolved_path`. |
| 635 | pub fn addFilePostContents( |
| 636 | self: *Manifest, |
| 637 | resolved_path: []const u8, |
| 638 | bytes: []const u8, |
| 639 | stat: File.Stat, |
| 640 | ) error{OutOfMemory}!void { |
| 641 | assert(self.manifest_file != null); |
| 642 | |
| 643 | const ch_file = try self.files.addOne(self.cache.gpa); |
| 644 | errdefer self.files.shrinkRetainingCapacity(self.files.items.len - 1); |
| 645 | |
| 646 | ch_file.* = .{ |
| 647 | .path = resolved_path, |
| 648 | .max_file_size = null, |
| 649 | .stat = stat, |
| 650 | .bin_digest = undefined, |
| 651 | .contents = null, |
| 652 | }; |
| 653 | |
| 654 | if (self.isProblematicTimestamp(ch_file.stat.mtime)) { |
| 655 | // The actual file has an unreliable timestamp, force it to be hashed |
| 656 | ch_file.stat.mtime = 0; |
| 657 | ch_file.stat.inode = 0; |
| 658 | } |
| 659 | |
| 660 | { |
| 661 | var hasher = hasher_init; |
| 662 | hasher.update(bytes); |
| 663 | hasher.final(&ch_file.bin_digest); |
| 664 | } |
| 665 | |
| 666 | self.hash.hasher.update(&ch_file.bin_digest); |
| 667 | } |
| 668 | |
| 618 | 669 | pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void { |
| 619 | 670 | assert(self.manifest_file != null); |
| 620 | 671 | |