diff --git a/lib/std/tar.zig b/lib/std/tar.zig index 121e7db248..db76e176b4 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -1,3 +1,4 @@ +<<<<<<< HEAD //! Tar archive is single ordinary file which can contain many files (or //! directories, symlinks, ...). It's build by series of blocks each size of 512 //! bytes. First block of each entry is header which defines type, name, size @@ -127,6 +128,8 @@ pub const Header = struct { return buffer[0 .. p.len + 1 + n.len]; } + /// When kind is symbolic_link linked-to name (target_path) is specified in + /// the linkname field. pub fn linkName(header: Header, buffer: *[LINK_NAME_SIZE]u8) []const u8 { const link_name = header.str(157, 100); if (link_name.len == 0) { @@ -619,6 +622,7 @@ fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8) !std.fs.File { return fs_file; } +// Creates a symbolic link at path `file_name` which points to `link_name`. fn createDirAndSymlink(dir: std.fs.Dir, link_name: []const u8, file_name: []const u8) !void { dir.symLink(link_name, file_name, .{}) catch |err| { if (err == error.FileNotFound) { @@ -841,3 +845,22 @@ test "tar header parse mode" { } } } + +test "create file and symlink" { + var root = std.testing.tmpDir(.{}); + defer root.cleanup(); + + _ = try createDirAndFile(root.dir, "file1"); + _ = try createDirAndFile(root.dir, "a/b/c/file2"); + + _ = createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { + // On Windows when developer mode is not enabled + if (err == error.AccessDenied) return error.SkipZigTest; + return err; + }; + _ = try createDirAndSymlink(root.dir, "../../../file1", "d/e/f/symlink2"); + + // Danglink symlnik, file created later + _ = try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); + _ = try createDirAndFile(root.dir, "g/h/i/file4"); +} diff --git a/lib/std/tar/test.zig b/lib/std/tar/test.zig index 67c4fe0198..bd45bf792a 100644 --- a/lib/std/tar/test.zig +++ b/lib/std/tar/test.zig @@ -1,5 +1,5 @@ -const std = @import("../std.zig"); -const tar = std.tar; +const std = @import("std"); +const tar = @import("../tar.zig"); const testing = std.testing; test "tar run Go test cases" { @@ -489,8 +489,7 @@ test "tar pipeToFileSystem" { try testing.expectError(error.FileNotFound, root.dir.statFile("empty")); try testing.expect((try root.dir.statFile("a/file")).kind == .file); - // TODO is there better way to test symlink try testing.expect((try root.dir.statFile("b/symlink")).kind == .file); // statFile follows symlink var buf: [32]u8 = undefined; - _ = try root.dir.readLink("b/symlink", &buf); + try testing.expectEqualSlices(u8, "../a/file", try root.dir.readLink("b/symlink", &buf)); }