mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
support xz compressed tarballs in the package manager
This includes a breaking change: std.compress.gzip.GzipStream renamed to std.compress.gzip.Decompress This follows the same naming convention as std.compress.xz so that the stream type can be passed as a comptime parameter.
This commit is contained in:
parent
ea9ded8758
commit
d94613c1d0
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Decompressor for GZIP data streams (RFC1952)
|
// Decompressor for GZIP data streams (RFC1952)
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("../std.zig");
|
||||||
const io = std.io;
|
const io = std.io;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
@ -17,10 +17,7 @@ const FCOMMENT = 1 << 4;
|
|||||||
|
|
||||||
const max_string_len = 1024;
|
const max_string_len = 1024;
|
||||||
|
|
||||||
/// TODO: the fully qualified namespace to this declaration is
|
pub fn Decompress(comptime ReaderType: type) type {
|
||||||
/// std.compress.gzip.GzipStream which has a redundant "gzip" in the name.
|
|
||||||
/// Instead, it should be `std.compress.gzip.Stream`.
|
|
||||||
pub fn GzipStream(comptime ReaderType: type) type {
|
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@ -154,14 +151,14 @@ pub fn GzipStream(comptime ReaderType: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gzipStream(allocator: mem.Allocator, reader: anytype) !GzipStream(@TypeOf(reader)) {
|
pub fn decompress(allocator: mem.Allocator, reader: anytype) !Decompress(@TypeOf(reader)) {
|
||||||
return GzipStream(@TypeOf(reader)).init(allocator, reader);
|
return Decompress(@TypeOf(reader)).init(allocator, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testReader(data: []const u8, comptime expected: []const u8) !void {
|
fn testReader(data: []const u8, comptime expected: []const u8) !void {
|
||||||
var in_stream = io.fixedBufferStream(data);
|
var in_stream = io.fixedBufferStream(data);
|
||||||
|
|
||||||
var gzip_stream = try gzipStream(testing.allocator, in_stream.reader());
|
var gzip_stream = try decompress(testing.allocator, in_stream.reader());
|
||||||
defer gzip_stream.deinit();
|
defer gzip_stream.deinit();
|
||||||
|
|
||||||
// Read and decompress the whole file
|
// Read and decompress the whole file
|
||||||
|
|||||||
@ -370,14 +370,11 @@ fn fetchAndUnpack(
|
|||||||
if (mem.endsWith(u8, uri.path, ".tar.gz")) {
|
if (mem.endsWith(u8, uri.path, ".tar.gz")) {
|
||||||
// I observed the gzip stream to read 1 byte at a time, so I am using a
|
// I observed the gzip stream to read 1 byte at a time, so I am using a
|
||||||
// buffered reader on the front of it.
|
// buffered reader on the front of it.
|
||||||
var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, req.reader());
|
try unpackTarball(gpa, &req, tmp_directory.handle, std.compress.gzip);
|
||||||
|
} else if (mem.endsWith(u8, uri.path, ".tar.xz")) {
|
||||||
var gzip_stream = try std.compress.gzip.gzipStream(gpa, br.reader());
|
// I have not checked what buffer sizes the xz decompression implementation uses
|
||||||
defer gzip_stream.deinit();
|
// by default, so the same logic applies for buffering the reader as for gzip.
|
||||||
|
try unpackTarball(gpa, &req, tmp_directory.handle, std.compress.xz);
|
||||||
try std.tar.pipeToFileSystem(tmp_directory.handle, gzip_stream.reader(), .{
|
|
||||||
.strip_components = 1,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return reportError(
|
return reportError(
|
||||||
ini,
|
ini,
|
||||||
@ -430,6 +427,22 @@ fn fetchAndUnpack(
|
|||||||
return createWithDir(gpa, fqn, global_cache_directory, pkg_dir_sub_path, build_zig_basename);
|
return createWithDir(gpa, fqn, global_cache_directory, pkg_dir_sub_path, build_zig_basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unpackTarball(
|
||||||
|
gpa: Allocator,
|
||||||
|
req: *std.http.Client.Request,
|
||||||
|
out_dir: fs.Dir,
|
||||||
|
comptime compression: type,
|
||||||
|
) !void {
|
||||||
|
var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, req.reader());
|
||||||
|
|
||||||
|
var decompress = try compression.decompress(gpa, br.reader());
|
||||||
|
defer decompress.deinit();
|
||||||
|
|
||||||
|
try std.tar.pipeToFileSystem(out_dir, decompress.reader(), .{
|
||||||
|
.strip_components = 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn reportError(
|
fn reportError(
|
||||||
ini: std.Ini,
|
ini: std.Ini,
|
||||||
comp_directory: Compilation.Directory,
|
comp_directory: Compilation.Directory,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user