| ... | ... | @@ -120,8 +120,10 @@ pub const Diagnostics = struct { |
| 120 | 120 | } |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | | /// pipeToFileSystem options |
| 124 | | pub const PipeOptions = struct { |
| 123 | /// Deprecated, renamed to `ExtractOptions`. |
| 124 | pub const PipeOptions = ExtractOptions; |
| 125 | |
| 126 | pub const ExtractOptions = struct { |
| 125 | 127 | /// Number of directory levels to skip when extracting files. |
| 126 | 128 | strip_components: u32 = 0, |
| 127 | 129 | /// How to handle the "mode" property of files from within the tar file. |
| ... | ... | @@ -580,8 +582,12 @@ pub const PaxIterator = struct { |
| 580 | 582 | } |
| 581 | 583 | }; |
| 582 | 584 | |
| 583 | | /// Saves tar file content to the file systems. |
| 584 | | pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOptions) !void { |
| 585 | /// Deprecated, renamed to `extract`. |
| 586 | pub const pipeToFileSystem = extract; |
| 587 | |
| 588 | /// Ingests tar file from `reader`, populating file contents within `dir`. If |
| 589 | /// any file would be extracted outside of `dir`, an error is return instead. |
| 590 | pub fn extract(io: Io, dir: Io.Dir, reader: *Io.Reader, options: ExtractOptions) !void { |
| 585 | 591 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| 586 | 592 | var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| 587 | 593 | var file_contents_buffer: [1024]u8 = undefined; |
| ... | ... | @@ -958,7 +964,7 @@ test Iterator { |
| 958 | 964 | } |
| 959 | 965 | } |
| 960 | 966 | |
| 961 | | test pipeToFileSystem { |
| 967 | test extract { |
| 962 | 968 | const io = testing.io; |
| 963 | 969 | // Example tar file is created from this tree structure: |
| 964 | 970 | // $ tree example |
| ... | ... | @@ -987,7 +993,7 @@ test pipeToFileSystem { |
| 987 | 993 | const dir = tmp.dir; |
| 988 | 994 | |
| 989 | 995 | // Save tar from reader to the file system `dir` |
| 990 | | pipeToFileSystem(io, dir, &reader, .{ |
| 996 | extract(io, dir, &reader, .{ |
| 991 | 997 | .mode_mode = .ignore, |
| 992 | 998 | .strip_components = 1, |
| 993 | 999 | .exclude_empty_directories = true, |
| ... | ... | @@ -1009,7 +1015,7 @@ test pipeToFileSystem { |
| 1009 | 1015 | ); |
| 1010 | 1016 | } |
| 1011 | 1017 | |
| 1012 | | test "pipeToFileSystem root_dir" { |
| 1018 | test "extract root_dir" { |
| 1013 | 1019 | const io = testing.io; |
| 1014 | 1020 | const data = @embedFile("tar/testdata/example.tar"); |
| 1015 | 1021 | var reader: Io.Reader = .fixed(data); |
| ... | ... | @@ -1021,7 +1027,7 @@ test "pipeToFileSystem root_dir" { |
| 1021 | 1027 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1022 | 1028 | defer diagnostics.deinit(); |
| 1023 | 1029 | |
| 1024 | | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1030 | extract(io, tmp.dir, &reader, .{ |
| 1025 | 1031 | .strip_components = 1, |
| 1026 | 1032 | .diagnostics = &diagnostics, |
| 1027 | 1033 | }) catch |err| { |
| ... | ... | @@ -1043,7 +1049,7 @@ test "pipeToFileSystem root_dir" { |
| 1043 | 1049 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1044 | 1050 | defer diagnostics.deinit(); |
| 1045 | 1051 | |
| 1046 | | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1052 | extract(io, tmp.dir, &reader, .{ |
| 1047 | 1053 | .strip_components = 0, |
| 1048 | 1054 | .diagnostics = &diagnostics, |
| 1049 | 1055 | }) catch |err| { |
| ... | ... | @@ -1068,7 +1074,7 @@ test "findRoot with single file archive" { |
| 1068 | 1074 | |
| 1069 | 1075 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1070 | 1076 | defer diagnostics.deinit(); |
| 1071 | | try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1077 | try extract(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1072 | 1078 | |
| 1073 | 1079 | try testing.expectEqualStrings("", diagnostics.root_dir); |
| 1074 | 1080 | } |
| ... | ... | @@ -1083,12 +1089,12 @@ test "findRoot without explicit root dir" { |
| 1083 | 1089 | |
| 1084 | 1090 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1085 | 1091 | defer diagnostics.deinit(); |
| 1086 | | try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1092 | try extract(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1087 | 1093 | |
| 1088 | 1094 | try testing.expectEqualStrings("root", diagnostics.root_dir); |
| 1089 | 1095 | } |
| 1090 | 1096 | |
| 1091 | | test "pipeToFileSystem strip_components" { |
| 1097 | test "extract strip_components" { |
| 1092 | 1098 | const io = testing.io; |
| 1093 | 1099 | const data = @embedFile("tar/testdata/example.tar"); |
| 1094 | 1100 | var reader: Io.Reader = .fixed(data); |
| ... | ... | @@ -1098,7 +1104,7 @@ test "pipeToFileSystem strip_components" { |
| 1098 | 1104 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1099 | 1105 | defer diagnostics.deinit(); |
| 1100 | 1106 | |
| 1101 | | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1107 | extract(io, tmp.dir, &reader, .{ |
| 1102 | 1108 | .strip_components = 3, |
| 1103 | 1109 | .diagnostics = &diagnostics, |
| 1104 | 1110 | }) catch |err| { |
| ... | ... | @@ -1120,7 +1126,7 @@ fn normalizePath(bytes: []u8) []u8 { |
| 1120 | 1126 | } |
| 1121 | 1127 | |
| 1122 | 1128 | // File system mode based on tar header mode and mode_mode options. |
| 1123 | | fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions { |
| 1129 | fn filePermissions(mode: u32, options: ExtractOptions) Io.File.Permissions { |
| 1124 | 1130 | return if (!Io.File.Permissions.has_executable_bit or options.mode_mode == .ignore or (mode & 0o100) == 0) |
| 1125 | 1131 | .default_file |
| 1126 | 1132 | else |
| ... | ... | @@ -1142,13 +1148,13 @@ test "executable bit" { |
| 1142 | 1148 | const S = std.posix.S; |
| 1143 | 1149 | const data = @embedFile("tar/testdata/example.tar"); |
| 1144 | 1150 | |
| 1145 | | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { |
| 1151 | for ([_]ExtractOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { |
| 1146 | 1152 | var reader: Io.Reader = .fixed(data); |
| 1147 | 1153 | |
| 1148 | 1154 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1149 | 1155 | //defer tmp.cleanup(); |
| 1150 | 1156 | |
| 1151 | | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1157 | extract(io, tmp.dir, &reader, .{ |
| 1152 | 1158 | .strip_components = 1, |
| 1153 | 1159 | .exclude_empty_directories = true, |
| 1154 | 1160 | .mode_mode = opt, |