| ... | @@ -47,10 +47,16 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.key_length); | ... | @@ -47,10 +47,16 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.key_length); |
| 47 | pub const File = struct { | 47 | pub const File = struct { |
| 48 | path: ?[]const u8, | 48 | path: ?[]const u8, |
| 49 | max_file_size: ?usize, | 49 | max_file_size: ?usize, |
| 50 | stat: fs.File.Stat, | 50 | stat: Stat, |
| 51 | bin_digest: BinDigest, | 51 | bin_digest: BinDigest, |
| 52 | contents: ?[]const u8, | 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 | pub fn deinit(self: *File, allocator: Allocator) void { | 60 | pub fn deinit(self: *File, allocator: Allocator) void { |
| 55 | if (self.path) |owned_slice| { | 61 | if (self.path) |owned_slice| { |
| 56 | allocator.free(owned_slice); | 62 | allocator.free(owned_slice); |
| ... | @@ -424,7 +430,11 @@ pub const Manifest = struct { | ... | @@ -424,7 +430,11 @@ pub const Manifest = struct { |
| 424 | if (!size_match or !mtime_match or !inode_match) { | 430 | if (!size_match or !mtime_match or !inode_match) { |
| 425 | self.manifest_dirty = true; | 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 | if (self.isProblematicTimestamp(cache_hash_file.stat.mtime)) { | 439 | if (self.isProblematicTimestamp(cache_hash_file.stat.mtime)) { |
| 430 | // The actual file has an unreliable timestamp, force it to be hashed | 440 | // The actual file has an unreliable timestamp, force it to be hashed |
| ... | @@ -530,7 +540,12 @@ pub const Manifest = struct { | ... | @@ -530,7 +540,12 @@ pub const Manifest = struct { |
| 530 | const file = try fs.cwd().openFile(ch_file.path.?, .{}); | 540 | const file = try fs.cwd().openFile(ch_file.path.?, .{}); |
| 531 | defer file.close(); | 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 | if (self.isProblematicTimestamp(ch_file.stat.mtime)) { | 550 | if (self.isProblematicTimestamp(ch_file.stat.mtime)) { |
| 536 | // The actual file has an unreliable timestamp, force it to be hashed | 551 | // The actual file has an unreliable timestamp, force it to be hashed |
| ... | @@ -615,6 +630,42 @@ pub const Manifest = struct { | ... | @@ -615,6 +630,42 @@ pub const Manifest = struct { |
| 615 | try self.populateFileHash(new_ch_file); | 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 | pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void { | 669 | pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void { |
| 619 | assert(self.manifest_file != null); | 670 | assert(self.manifest_file != null); |
| 620 | | 671 | |