diff --git a/git.zig b/git.zig index e1a14255391b0e1c95ee4c39cee452a2e625d3e9..f0b391a792babf5cdd7f97dd11f62d5880abc6c1 100644 --- a/git.zig +++ b/git.zig @@ -4,6 +4,7 @@ const top = @This(); const time = @import("time"); const extras = @import("extras"); const tracer = @import("tracer"); +const nfs = @import("nfs"); // 40 is length of sha1 hash pub const Id = *const [40]u8; @@ -55,7 +56,7 @@ pub fn version(alloc: std.mem.Allocator) !string { /// Returns the result of running `git rev-parse HEAD` /// dir must already be pointing at the .git folder // TODO this doesnt handle when there are 0 commits -pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !?CommitId { +pub fn getHEAD(alloc: std.mem.Allocator, dir: nfs.Dir) !?CommitId { const t = tracer.trace(@src(), "", .{}); defer t.end(); @@ -63,7 +64,10 @@ pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !?CommitId { if (std.mem.startsWith(u8, h, "ref:")) { blk: { - const reffile = dir.readFileAlloc(alloc, h[5..], 1024) catch |err| switch (err) { + var buf: [std.fs.max_path_bytes]u8 = undefined; + @memcpy((&buf).ptr, h[5..]); + buf[h[5..].len] = 0; + const reffile = dir.readFileAlloc(alloc, buf[0..h[5..].len :0], 1024) catch |err| switch (err) { error.FileNotFound => break :blk, else => |e| return e, }; @@ -101,13 +105,13 @@ fn ensureObjId(comptime T: type, input: string) T { // TODO make this return a Reader when we implement it ourselves // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !string { +pub fn getObject(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !string { const t = tracer.trace(@src(), " {s}", .{obj}); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "cat-file", "-p", obj }, .max_output_bytes = 1024 * 1024 * 1024, }); @@ -118,13 +122,13 @@ pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !string { // TODO make this inspect .git/objects manually // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn getObjectSize(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !u64 { +pub fn getObjectSize(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !u64 { const t = tracer.trace(@src(), " {s}", .{obj}); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "cat-file", "-s", obj }, }); extras.assertLog(result.term == .Exited and result.term.Exited == 0, "{s}", .{result.stderr}); @@ -134,13 +138,13 @@ pub fn getObjectSize(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !u64 { // TODO make this inspect .git manually // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn isType(alloc: std.mem.Allocator, dir: std.fs.Dir, maybeobj: Id, typ: Tree.Object.Id.Tag) !bool { +pub fn isType(alloc: std.mem.Allocator, dir: nfs.Dir, maybeobj: Id, typ: Tree.Object.Id.Tag) !bool { const t = tracer.trace(@src(), " {s} = {s} ?", .{ maybeobj, @tagName(typ) }); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "cat-file", "-t", maybeobj }, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -151,13 +155,13 @@ pub fn isType(alloc: std.mem.Allocator, dir: std.fs.Dir, maybeobj: Id, typ: Tree // TODO make this inspect .git manually // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn getType(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !Tree.Object.Id.Tag { +pub fn getType(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !Tree.Object.Id.Tag { const t = tracer.trace(@src(), " {s}", .{obj}); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "cat-file", "-t", obj }, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -169,13 +173,13 @@ pub fn getType(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !Tree.Object. // TODO make a version of this that accepts an array of sub_paths and searches all of them at once, so as to not lose spot in history when searching for many old paths // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn revList(alloc: std.mem.Allocator, dir: std.fs.Dir, comptime count: u31, from: CommitId, sub_path: string) !string { +pub fn revList(alloc: std.mem.Allocator, dir: nfs.Dir, comptime count: u31, from: CommitId, sub_path: string) !string { const t = tracer.trace(@src(), "({d}) {s} -- {s}", .{ count, from.id, sub_path }); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "rev-list", @@ -412,14 +416,14 @@ pub const Tree = struct { // TODO make this inspect .git manually // TODO make this return a Reader when we implement it ourselves -pub fn getTreeDiff(alloc: std.mem.Allocator, dir: std.fs.Dir, commitid: CommitId, parentid: ?CommitId) !string { +pub fn getTreeDiff(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitId, parentid: ?CommitId) !string { const t = tracer.trace(@src(), "", .{}); defer t.end(); if (parentid == null) { const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), // 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is a hardcode for the empty tree in git sha1 // result of `printf | git hash-object -t tree --stdin` .argv = &.{ "git", "diff-tree", "-p", "--raw", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", commitid.id }, @@ -430,7 +434,7 @@ pub fn getTreeDiff(alloc: std.mem.Allocator, dir: std.fs.Dir, commitid: CommitId } const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "diff-tree", "-p", "--raw", parentid.?.id, commitid.id }, .max_output_bytes = 1024 * 1024 * 1024, }); @@ -681,13 +685,13 @@ pub const TreeDiff = struct { }; }; -pub fn getBranches(alloc: std.mem.Allocator, dir: std.fs.Dir) ![]const Ref { +pub fn getBranches(alloc: std.mem.Allocator, dir: nfs.Dir) ![]const Ref { const t = tracer.trace(@src(), "", .{}); defer t.end(); const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "show-ref", "--heads" }, .max_output_bytes = 1024 * 1024 * 1024, }); @@ -707,7 +711,7 @@ pub fn getBranches(alloc: std.mem.Allocator, dir: std.fs.Dir) ![]const Ref { return list.toOwnedSlice(); } -pub fn getTags(alloc: std.mem.Allocator, dir: std.fs.Dir) ![]const Ref { +pub fn getTags(alloc: std.mem.Allocator, dir: nfs.Dir) ![]const Ref { const t = tracer.trace(@src(), "", .{}); defer t.end(); @@ -717,7 +721,7 @@ pub fn getTags(alloc: std.mem.Allocator, dir: std.fs.Dir) ![]const Ref { // 7dfd3948a9095f0253bfba60fed52895ffbf84bb refs/tags/15.3.2 const result = try std.process.Child.run(.{ .allocator = alloc, - .cwd_dir = dir, + .cwd_dir = dir.to_std(), .argv = &.{ "git", "show-ref", "--tags", "--dereference" }, .max_output_bytes = 1024 * 1024 * 1024, }); diff --git a/licenses.txt b/licenses.txt index 45c688c3d1ca2fe4f3bee649417ec3235ac4295c..235f7d45c03d619d9a2641b8d1c3156ddd77f693 100644 --- a/licenses.txt +++ b/licenses.txt @@ -1,7 +1,18 @@ MIT: = https://spdx.org/licenses/MIT - This +- git https://github.com/nektro/zig-errno - git https://github.com/nektro/zig-expect - git https://github.com/nektro/zig-extras +- git https://github.com/nektro/zig-libc +- git https://github.com/nektro/zig-sys-libc - git https://github.com/nektro/zig-time - git https://github.com/nektro/zig-tracer + +MPL-2.0: += https://spdx.org/licenses/MPL-2.0 +- git https://github.com/nektro/zig-nfs +- git https://github.com/nektro/zig-nio + +Unspecified: +- system_lib c diff --git a/test.zig b/test.zig index 8b9b53c837e756c20bc1ad67fdf61eb3ce835ecf..766bd53fa182b3604ff16e8f12c79808193d2a4d 100644 --- a/test.zig +++ b/test.zig @@ -2,6 +2,7 @@ const std = @import("std"); const git = @import("git"); const extras = @import("extras"); const expect = @import("expect").expect; +const nfs = @import("nfs"); test { _ = &git.version; @@ -14,7 +15,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); const branch_refs = try git.getBranches(alloc, git_dir); const branch_names = try extras.mapBy(alloc, branch_refs, .label); @@ -25,7 +26,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.getObject(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e")).toEqualString( \\tree 5403fecad0fde9120535321f222a061abc2849d9 @@ -42,7 +43,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.getObjectSize(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e")).toEqual(229); try expect(try git.getObjectSize(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e")).toEqual(45 + 47 + 55 + 58 + 0 + 18 + 6); @@ -52,7 +53,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.isType(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e", .blob)).toEqual(false); try expect(try git.isType(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e", .tree)).toEqual(false); @@ -64,7 +65,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.getType(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e")).toEqual(.commit); } @@ -73,7 +74,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); const c = try git.parseCommit(alloc, try git.getObject(alloc, git_dir, "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e")); try expect(c.tree.id).toEqualString("5403fecad0fde9120535321f222a061abc2849d9"); @@ -95,7 +96,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.getObject(alloc, git_dir, "5403fecad0fde9120535321f222a061abc2849d9")).toEqualString( // zig fmt: off @@ -113,7 +114,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); const t = try git.parseTree(alloc, try git.getObject(alloc, git_dir, "5403fecad0fde9120535321f222a061abc2849d9")); // TODO: test fields when we upgrade to 0.14 and have decl literals @@ -137,7 +138,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); try expect(try git.getTreeDiff(alloc, git_dir, .{ .id = "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e" }, .{ .id = "c39f57f6bb01664a7146ddbfc3debe76ec135f44" })).toEqualString( // zig fmt: off @@ -171,7 +172,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); const t = try git.parseTreeDiffMeta(try git.getTreeDiff(alloc, git_dir, .{ .id = "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e" }, .{ .id = "c39f57f6bb01664a7146ddbfc3debe76ec135f44" })); try expect(t.files_changed).toEqual(1); @@ -183,7 +184,7 @@ test { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const alloc = arena.allocator(); - var git_dir = try std.fs.cwd().openDir(".git", .{}); + const git_dir = try nfs.cwd().openDir(".git", .{}); defer git_dir.close(); const t = try git.parseTreeDiff(alloc, try git.getTreeDiff(alloc, git_dir, .{ .id = "a542da41f1f0c59fdd0e1527cf5ff9de3f6a0c8e" }, .{ .id = "c39f57f6bb01664a7146ddbfc3debe76ec135f44" })); _ = t; // TODO: test fields when we upgrade to 0.14 and have decl literals diff --git a/zig.mod b/zig.mod index ed46b4389cf7e44ad207d600587e2bd154469f1d..5557c98fb680fa012a206e37b6a15e6e57b50666 100644 --- a/zig.mod +++ b/zig.mod @@ -7,6 +7,8 @@ dependencies: - src: git https://github.com/nektro/zig-time - src: git https://github.com/nektro/zig-extras - src: git https://github.com/nektro/zig-tracer + - src: git https://github.com/nektro/zig-nfs root_dependencies: - src: git https://github.com/nektro/zig-extras - src: git https://github.com/nektro/zig-expect + - src: git https://github.com/nektro/zig-nfs