| ... | ... | @@ -51,11 +51,11 @@ pub const Diagnostics = struct { |
| 51 | 51 | }, |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | | fn findRoot(d: *Diagnostics, path: []const u8) !void { |
| 54 | fn findRoot(d: *Diagnostics, kind: FileKind, path: []const u8) !void { |
| 55 | 55 | if (path.len == 0) return; |
| 56 | 56 | |
| 57 | 57 | d.entries += 1; |
| 58 | | const root_dir = rootDir(path); |
| 58 | const root_dir = rootDir(path, kind); |
| 59 | 59 | if (d.entries == 1) { |
| 60 | 60 | d.root_dir = try d.allocator.dupe(u8, root_dir); |
| 61 | 61 | return; |
| ... | ... | @@ -67,24 +67,31 @@ pub const Diagnostics = struct { |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | // Returns root dir of the path, assumes non empty path. |
| 70 | | fn rootDir(path: []const u8) []const u8 { |
| 70 | fn rootDir(path: []const u8, kind: FileKind) []const u8 { |
| 71 | 71 | const start_index: usize = if (path[0] == '/') 1 else 0; |
| 72 | 72 | const end_index: usize = if (path[path.len - 1] == '/') path.len - 1 else path.len; |
| 73 | 73 | const buf = path[start_index..end_index]; |
| 74 | 74 | if (std.mem.indexOfScalarPos(u8, buf, 0, '/')) |idx| { |
| 75 | 75 | return buf[0..idx]; |
| 76 | 76 | } |
| 77 | | return buf; |
| 77 | |
| 78 | return switch (kind) { |
| 79 | .file => "", |
| 80 | .sym_link => "", |
| 81 | .directory => buf, |
| 82 | }; |
| 78 | 83 | } |
| 79 | 84 | |
| 80 | 85 | test rootDir { |
| 81 | 86 | const expectEqualStrings = testing.expectEqualStrings; |
| 82 | | try expectEqualStrings("a", rootDir("a")); |
| 83 | | try expectEqualStrings("b", rootDir("b")); |
| 84 | | try expectEqualStrings("c", rootDir("/c")); |
| 85 | | try expectEqualStrings("d", rootDir("/d/")); |
| 86 | | try expectEqualStrings("a", rootDir("a/b")); |
| 87 | | try expectEqualStrings("a", rootDir("a/b/c")); |
| 87 | try expectEqualStrings("", rootDir("a", .file)); |
| 88 | try expectEqualStrings("a", rootDir("a", .directory)); |
| 89 | try expectEqualStrings("b", rootDir("b", .directory)); |
| 90 | try expectEqualStrings("c", rootDir("/c", .directory)); |
| 91 | try expectEqualStrings("d", rootDir("/d/", .directory)); |
| 92 | try expectEqualStrings("a", rootDir("a/b", .directory)); |
| 93 | try expectEqualStrings("a", rootDir("a/b", .file)); |
| 94 | try expectEqualStrings("a", rootDir("a/b/c", .directory)); |
| 88 | 95 | } |
| 89 | 96 | |
| 90 | 97 | pub fn deinit(d: *Diagnostics) void { |
| ... | ... | @@ -637,7 +644,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions) |
| 637 | 644 | continue; |
| 638 | 645 | } |
| 639 | 646 | if (options.diagnostics) |d| { |
| 640 | | try d.findRoot(file_name); |
| 647 | try d.findRoot(file.kind, file_name); |
| 641 | 648 | } |
| 642 | 649 | |
| 643 | 650 | switch (file.kind) { |
| ... | ... | @@ -1093,6 +1100,21 @@ test "pipeToFileSystem root_dir" { |
| 1093 | 1100 | } |
| 1094 | 1101 | } |
| 1095 | 1102 | |
| 1103 | test "findRoot with single file archive" { |
| 1104 | const data = @embedFile("tar/testdata/22752.tar"); |
| 1105 | var fbs = std.io.fixedBufferStream(data); |
| 1106 | const reader = fbs.reader(); |
| 1107 | |
| 1108 | var tmp = testing.tmpDir(.{}); |
| 1109 | defer tmp.cleanup(); |
| 1110 | |
| 1111 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1112 | defer diagnostics.deinit(); |
| 1113 | try pipeToFileSystem(tmp.dir, reader, .{ .diagnostics = &diagnostics }); |
| 1114 | |
| 1115 | try testing.expectEqualStrings("", diagnostics.root_dir); |
| 1116 | } |
| 1117 | |
| 1096 | 1118 | test "findRoot without explicit root dir" { |
| 1097 | 1119 | const data = @embedFile("tar/testdata/19820.tar"); |
| 1098 | 1120 | var fbs = std.io.fixedBufferStream(data); |