authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-10-16 20:51:30+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-17 19:02:00-04:00
logf58811a58a592a4e5844e66919b18211dc5f6e59
tree56966691bf2bacc4ab756c4bb4e654f5d1adf598
parent25400fadf868376635ac6f8d0c40ff8f289f5f19

package fetching: support .tar.zst archives


1 files changed, 18 insertions(+), 0 deletions(-)

src/Package/Fetch.zig+18
...@@ -756,12 +756,14 @@ const FileType = enum {...@@ -756,12 +756,14 @@ const FileType = enum {
756 tar,756 tar,
757 @"tar.gz",757 @"tar.gz",
758 @"tar.xz",758 @"tar.xz",
759 @"tar.zst",
759 git_pack,760 git_pack,
760761
761 fn fromPath(file_path: []const u8) ?FileType {762 fn fromPath(file_path: []const u8) ?FileType {
762 if (ascii.endsWithIgnoreCase(file_path, ".tar")) return .tar;763 if (ascii.endsWithIgnoreCase(file_path, ".tar")) return .tar;
763 if (ascii.endsWithIgnoreCase(file_path, ".tar.gz")) return .@"tar.gz";764 if (ascii.endsWithIgnoreCase(file_path, ".tar.gz")) return .@"tar.gz";
764 if (ascii.endsWithIgnoreCase(file_path, ".tar.xz")) return .@"tar.xz";765 if (ascii.endsWithIgnoreCase(file_path, ".tar.xz")) return .@"tar.xz";
766 if (ascii.endsWithIgnoreCase(file_path, ".tar.zst")) return .@"tar.zst";
765 return null;767 return null;
766 }768 }
767769
...@@ -979,6 +981,9 @@ fn unpackResource(...@@ -979,6 +981,9 @@ fn unpackResource(
979 if (ascii.eqlIgnoreCase(content_type, "application/x-xz"))981 if (ascii.eqlIgnoreCase(content_type, "application/x-xz"))
980 break :ft .@"tar.xz";982 break :ft .@"tar.xz";
981983
984 if (ascii.eqlIgnoreCase(content_type, "application/zstd"))
985 break :ft .@"tar.zst";
986
982 if (!ascii.eqlIgnoreCase(content_type, "application/octet-stream")) {987 if (!ascii.eqlIgnoreCase(content_type, "application/octet-stream")) {
983 return f.fail(f.location_tok, try eb.printString(988 return f.fail(f.location_tok, try eb.printString(
984 "unrecognized 'Content-Type' header: '{s}'",989 "unrecognized 'Content-Type' header: '{s}'",
...@@ -1019,6 +1024,7 @@ fn unpackResource(...@@ -1019,6 +1024,7 @@ fn unpackResource(
1019 .tar => try unpackTarball(f, tmp_directory.handle, resource.reader()),1024 .tar => try unpackTarball(f, tmp_directory.handle, resource.reader()),
1020 .@"tar.gz" => try unpackTarballCompressed(f, tmp_directory.handle, resource, std.compress.gzip),1025 .@"tar.gz" => try unpackTarballCompressed(f, tmp_directory.handle, resource, std.compress.gzip),
1021 .@"tar.xz" => try unpackTarballCompressed(f, tmp_directory.handle, resource, std.compress.xz),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 .git_pack => unpackGitPack(f, tmp_directory.handle, resource) catch |err| switch (err) {1028 .git_pack => unpackGitPack(f, tmp_directory.handle, resource) catch |err| switch (err) {
1023 error.FetchFailed => return error.FetchFailed,1029 error.FetchFailed => return error.FetchFailed,
1024 error.OutOfMemory => return error.OutOfMemory,1030 error.OutOfMemory => return error.OutOfMemory,
...@@ -1030,6 +1036,18 @@ fn unpackResource(...@@ -1030,6 +1036,18 @@ fn unpackResource(
1030 }1036 }
1031}1037}
10321038
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
1041const 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
1033fn unpackTarballCompressed(1051fn unpackTarballCompressed(
1034 f: *Fetch,1052 f: *Fetch,
1035 out_dir: fs.Dir,1053 out_dir: fs.Dir,