@@ -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 );
0 commit comments