mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:04:43 +01:00
Use / as path separator when writing tar files
The tar format expects `/`, although some untar implementations do seem to handle Windows-style `\` path separators (7-Zip at least). The tar.Writer API can't really enforce this, though, as doing so would effectively make `\` an illegal character when it's really not. So, it's up to the user to provide paths with the correct path separators. `Build/WebServer.zig` will still output tars with `\` as a path separator on Windows, but that's currently only used during fuzzing which is not yet implemented on Windows.
This commit is contained in:
parent
46658257f4
commit
25ef201ace
5 changed files with 47 additions and 3 deletions
|
|
@ -208,6 +208,9 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
|
|||
var archiver: std.tar.Writer = .{ .underlying_writer = &response.writer };
|
||||
archiver.prefix = "std";
|
||||
|
||||
var path_buf: std.ArrayList(u8) = .empty;
|
||||
defer path_buf.deinit(gpa);
|
||||
|
||||
while (try walker.next(io)) |entry| {
|
||||
switch (entry.kind) {
|
||||
.file => {
|
||||
|
|
@ -227,7 +230,17 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
|
|||
.interface = Io.File.Reader.initInterface(&.{}),
|
||||
.size = stat.size,
|
||||
};
|
||||
try archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime);
|
||||
|
||||
const posix_path = if (comptime std.fs.path.sep == std.fs.path.sep_posix)
|
||||
entry.path
|
||||
else blk: {
|
||||
path_buf.clearRetainingCapacity();
|
||||
try path_buf.appendSlice(gpa, entry.path);
|
||||
std.mem.replaceScalar(u8, path_buf.items, std.fs.path.sep, std.fs.path.sep_posix);
|
||||
break :blk path_buf.items;
|
||||
};
|
||||
|
||||
try archiver.writeFileTimestamp(posix_path, &file_reader, stat.mtime);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -526,6 +526,10 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons
|
|||
// resulting in modules named "" and "src". The compiler needs to tell the build system
|
||||
// about the module graph so that the build system can correctly encode this information in
|
||||
// the tar file.
|
||||
//
|
||||
// Additionally, this needs to ensure that all path separators for both prefix and
|
||||
// sub_path are using the POSIX-style `/` on platforms that don't use it as their native
|
||||
// path separator.
|
||||
archiver.prefix = path.root_dir.path orelse graph.cache.cwd;
|
||||
try archiver.writeFile(path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ pub const Options = struct {
|
|||
};
|
||||
|
||||
underlying_writer: *Io.Writer,
|
||||
/// Assumed to use `/` for any path separators.
|
||||
prefix: []const u8 = "",
|
||||
|
||||
const Error = error{
|
||||
|
|
@ -26,6 +27,7 @@ const Error = error{
|
|||
};
|
||||
|
||||
/// Sets prefix for all other write* method paths.
|
||||
/// `root` is assumed to use `/` for any path separators.
|
||||
pub fn setRoot(w: *Writer, root: []const u8) Error!void {
|
||||
if (root.len > 0)
|
||||
try w.writeDir(root, .{});
|
||||
|
|
@ -41,6 +43,7 @@ pub const WriteFileError = Io.Writer.FileError || Error || Io.File.Reader.SizeEr
|
|||
|
||||
pub fn writeFileTimestamp(
|
||||
w: *Writer,
|
||||
/// Assumed to use `/` for any path separators.
|
||||
sub_path: []const u8,
|
||||
file_reader: *Io.File.Reader,
|
||||
mtime: Io.Timestamp,
|
||||
|
|
@ -50,6 +53,7 @@ pub fn writeFileTimestamp(
|
|||
|
||||
pub fn writeFile(
|
||||
w: *Writer,
|
||||
/// Assumed to use `/` for any path separators.
|
||||
sub_path: []const u8,
|
||||
file_reader: *Io.File.Reader,
|
||||
/// If you want to match the file format's expectations, it wants number of
|
||||
|
|
@ -76,6 +80,7 @@ pub const WriteFileStreamError = Error || Io.Reader.StreamError;
|
|||
/// from `reader`, or returns `error.EndOfStream`.
|
||||
pub fn writeFileStream(
|
||||
w: *Writer,
|
||||
/// Assumed to use `/` for any path separators.
|
||||
sub_path: []const u8,
|
||||
size: u64,
|
||||
reader: *Io.Reader,
|
||||
|
|
@ -87,7 +92,13 @@ pub fn writeFileStream(
|
|||
}
|
||||
|
||||
/// Writes file using bytes buffer `content` for size and file content.
|
||||
pub fn writeFileBytes(w: *Writer, sub_path: []const u8, content: []const u8, options: Options) Error!void {
|
||||
pub fn writeFileBytes(
|
||||
w: *Writer,
|
||||
/// Assumed to use `/` for all path separators.
|
||||
sub_path: []const u8,
|
||||
content: []const u8,
|
||||
options: Options,
|
||||
) Error!void {
|
||||
try w.writeHeader(.regular, sub_path, "", content.len, options);
|
||||
try w.underlying_writer.writeAll(content);
|
||||
try w.writePadding(content.len);
|
||||
|
|
|
|||
|
|
@ -5440,6 +5440,9 @@ fn docsCopyModule(
|
|||
var archiver: std.tar.Writer = .{ .underlying_writer = &tar_file_writer.interface };
|
||||
archiver.prefix = name;
|
||||
|
||||
var path_buf: std.ArrayList(u8) = .empty;
|
||||
defer path_buf.deinit(comp.gpa);
|
||||
|
||||
var buffer: [1024]u8 = undefined;
|
||||
|
||||
while (try walker.next(io)) |entry| {
|
||||
|
|
@ -5460,7 +5463,16 @@ fn docsCopyModule(
|
|||
const stat = try file.stat(io);
|
||||
var file_reader: Io.File.Reader = .initSize(file, io, &buffer, stat.size);
|
||||
|
||||
archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| {
|
||||
const posix_path = if (comptime std.fs.path.sep == std.fs.path.sep_posix)
|
||||
entry.path
|
||||
else blk: {
|
||||
path_buf.clearRetainingCapacity();
|
||||
try path_buf.appendSlice(comp.gpa, entry.path);
|
||||
std.mem.replaceScalar(u8, path_buf.items, std.fs.path.sep, std.fs.path.sep_posix);
|
||||
break :blk path_buf.items;
|
||||
};
|
||||
|
||||
archiver.writeFileTimestamp(posix_path, &file_reader, stat.mtime) catch |err| {
|
||||
return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive {f}{s}: {t}", .{
|
||||
root.fmt(comp), entry.path, err,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -402,6 +402,10 @@ pub const JobQueue = struct {
|
|||
},
|
||||
}
|
||||
const entry_path = try arena.dupe(u8, entry.path);
|
||||
// If necessary, normalize path separators to POSIX-style since the tar format requires that.
|
||||
if (comptime std.fs.path.sep != std.fs.path.sep_posix) {
|
||||
std.mem.replaceScalar(u8, entry_path, std.fs.path.sep, std.fs.path.sep_posix);
|
||||
}
|
||||
try scanned_files.append(gpa, entry_path);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue