| ... | ... | @@ -756,12 +756,14 @@ const FileType = enum { |
| 756 | 756 | tar, |
| 757 | 757 | @"tar.gz", |
| 758 | 758 | @"tar.xz", |
| 759 | @"tar.zst", |
| 759 | 760 | git_pack, |
| 760 | 761 | |
| 761 | 762 | fn fromPath(file_path: []const u8) ?FileType { |
| 762 | 763 | if (ascii.endsWithIgnoreCase(file_path, ".tar")) return .tar; |
| 763 | 764 | if (ascii.endsWithIgnoreCase(file_path, ".tar.gz")) return .@"tar.gz"; |
| 764 | 765 | if (ascii.endsWithIgnoreCase(file_path, ".tar.xz")) return .@"tar.xz"; |
| 766 | if (ascii.endsWithIgnoreCase(file_path, ".tar.zst")) return .@"tar.zst"; |
| 765 | 767 | return null; |
| 766 | 768 | } |
| 767 | 769 | |
| ... | ... | @@ -979,6 +981,9 @@ fn unpackResource( |
| 979 | 981 | if (ascii.eqlIgnoreCase(content_type, "application/x-xz")) |
| 980 | 982 | break :ft .@"tar.xz"; |
| 981 | 983 | |
| 984 | if (ascii.eqlIgnoreCase(content_type, "application/zstd")) |
| 985 | break :ft .@"tar.zst"; |
| 986 | |
| 982 | 987 | if (!ascii.eqlIgnoreCase(content_type, "application/octet-stream")) { |
| 983 | 988 | return f.fail(f.location_tok, try eb.printString( |
| 984 | 989 | "unrecognized 'Content-Type' header: '{s}'", |
| ... | ... | @@ -1019,6 +1024,7 @@ fn unpackResource( |
| 1019 | 1024 | .tar => try unpackTarball(f, tmp_directory.handle, resource.reader()), |
| 1020 | 1025 | .@"tar.gz" => try unpackTarballCompressed(f, tmp_directory.handle, resource, std.compress.gzip), |
| 1021 | 1026 | .@"tar.xz" => try unpackTarballCompressed(f, tmp_directory.handle, resource, std.compress.xz), |
| 1027 | .@"tar.zst" => try unpackTarballCompressed(f, tmp_directory.handle, resource, ZstdWrapper), |
| 1022 | 1028 | .git_pack => unpackGitPack(f, tmp_directory.handle, resource) catch |err| switch (err) { |
| 1023 | 1029 | error.FetchFailed => return error.FetchFailed, |
| 1024 | 1030 | error.OutOfMemory => return error.OutOfMemory, |
| ... | ... | @@ -1030,6 +1036,18 @@ fn unpackResource( |
| 1030 | 1036 | } |
| 1031 | 1037 | } |
| 1032 | 1038 | |
| 1039 | // due to slight differences in the API of std.compress.(gzip|xz) and std.compress.zstd, zstd is |
| 1040 | // wrapped for generic use in unpackTarballCompressed: see github.com/ziglang/zig/issues/14739 |
| 1041 | const ZstdWrapper = struct { |
| 1042 | fn DecompressType(comptime T: type) type { |
| 1043 | return error{}!std.compress.zstd.DecompressStream(T, .{}); |
| 1044 | } |
| 1045 | |
| 1046 | fn decompress(allocator: Allocator, reader: anytype) DecompressType(@TypeOf(reader)) { |
| 1047 | return std.compress.zstd.decompressStream(allocator, reader); |
| 1048 | } |
| 1049 | }; |
| 1050 | |
| 1033 | 1051 | fn unpackTarballCompressed( |
| 1034 | 1052 | f: *Fetch, |
| 1035 | 1053 | out_dir: fs.Dir, |