| ... | @@ -1329,7 +1329,7 @@ fn computeHash( | ... | @@ -1329,7 +1329,7 @@ fn computeHash( |
| 1329 | const hashed_file = try arena.create(HashedFile); | 1329 | const hashed_file = try arena.create(HashedFile); |
| 1330 | hashed_file.* = .{ | 1330 | hashed_file.* = .{ |
| 1331 | .fs_path = fs_path, | 1331 | .fs_path = fs_path, |
| 1332 | .normalized_path = try normalizePath(arena, fs_path), | 1332 | .normalized_path = try normalizePathAlloc(arena, fs_path), |
| 1333 | .kind = kind, | 1333 | .kind = kind, |
| 1334 | .hash = undefined, // to be populated by the worker | 1334 | .hash = undefined, // to be populated by the worker |
| 1335 | .failure = undefined, // to be populated by the worker | 1335 | .failure = undefined, // to be populated by the worker |
| ... | @@ -1429,6 +1429,12 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void | ... | @@ -1429,6 +1429,12 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void |
| 1429 | }, | 1429 | }, |
| 1430 | .sym_link => { | 1430 | .sym_link => { |
| 1431 | const link_name = try dir.readLink(hashed_file.fs_path, &buf); | 1431 | const link_name = try dir.readLink(hashed_file.fs_path, &buf); |
| | 1432 | if (fs.path.sep != canonical_sep) { |
| | 1433 | // Package hashes are intended to be consistent across |
| | 1434 | // platforms which means we must normalize path separators |
| | 1435 | // inside symlinks. |
| | 1436 | normalizePath(link_name); |
| | 1437 | } |
| 1432 | hasher.update(link_name); | 1438 | hasher.update(link_name); |
| 1433 | }, | 1439 | }, |
| 1434 | } | 1440 | } |
| ... | @@ -1484,22 +1490,20 @@ const HashedFile = struct { | ... | @@ -1484,22 +1490,20 @@ const HashedFile = struct { |
| 1484 | | 1490 | |
| 1485 | /// Make a file system path identical independently of operating system path inconsistencies. | 1491 | /// Make a file system path identical independently of operating system path inconsistencies. |
| 1486 | /// This converts backslashes into forward slashes. | 1492 | /// This converts backslashes into forward slashes. |
| 1487 | fn normalizePath(arena: Allocator, fs_path: []const u8) ![]const u8 { | 1493 | fn normalizePathAlloc(arena: Allocator, fs_path: []const u8) ![]const u8 { |
| 1488 | const canonical_sep = '/'; | 1494 | if (fs.path.sep == canonical_sep) return fs_path; |
| 1489 | | | |
| 1490 | if (fs.path.sep == canonical_sep) | | |
| 1491 | return fs_path; | | |
| 1492 | | | |
| 1493 | const normalized = try arena.dupe(u8, fs_path); | 1495 | const normalized = try arena.dupe(u8, fs_path); |
| 1494 | for (normalized) |*byte| { | 1496 | normalizePath(normalized); |
| 1495 | switch (byte.*) { | | |
| 1496 | fs.path.sep => byte.* = canonical_sep, | | |
| 1497 | else => continue, | | |
| 1498 | } | | |
| 1499 | } | | |
| 1500 | return normalized; | 1497 | return normalized; |
| 1501 | } | 1498 | } |
| 1502 | | 1499 | |
| | 1500 | const canonical_sep = fs.path.sep_posix; |
| | 1501 | |
| | 1502 | fn normalizePath(bytes: []u8) void { |
| | 1503 | assert(fs.path.sep != canonical_sep); |
| | 1504 | std.mem.replaceScalar(u8, bytes, fs.path.sep, canonical_sep); |
| | 1505 | } |
| | 1506 | |
| 1503 | const Filter = struct { | 1507 | const Filter = struct { |
| 1504 | include_paths: std.StringArrayHashMapUnmanaged(void) = .{}, | 1508 | include_paths: std.StringArrayHashMapUnmanaged(void) = .{}, |
| 1505 | | 1509 | |