X-Git-Url: https://gitweb.ps.run/ziggit/blobdiff_plain/107927604089c6fc63b5f5fef633542352f5269d..8bb933882251b1c52c42f95af32c163149005396:/git.zig diff --git a/git.zig b/git.zig index 4dbe474..80e9aac 100644 --- a/git.zig +++ b/git.zig @@ -23,6 +23,11 @@ const Tree = std.ArrayList(TreeEntry); const Blob = struct { data: []u8, }; +const ParsedObject = union(enum) { + c: Commit, + t: Tree, + b: Blob, +}; const Object = struct { kind: u3, data: []u8, @@ -33,7 +38,7 @@ const Object = struct { .data = data, }; } - pub fn parse(self: Object, alloc: Alloc) !union(enum) { c: Commit, t: Tree, b: Blob } { + pub fn parse(self: Object, alloc: Alloc) !ParsedObject { switch (self.kind) { 1 => { const authorOffset = std.mem.indexOf(u8, self.data, "author ") orelse return error.InvalidCommitFormat; @@ -350,7 +355,9 @@ const PackFile = struct { const pckReader = self.pckFile.reader().any(); try self.pckFile.seekTo(offset); - return try self.readObject(pckReader); + const o = try self.readObject(pckReader); + + return o; } return null; } @@ -403,7 +410,11 @@ const Repo = struct { }; test "print HEAD" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); const head = try repo.getHead(); @@ -412,7 +423,11 @@ test "print HEAD" { } test "parse idx" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); if (repo.packfile) |packfile| { @@ -422,28 +437,36 @@ test "parse idx" { } test "get object" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); const head = try repo.getHead(); if (try repo.getObject(head)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); std.debug.print("object({}): {s}\n", .{ o.kind, o.data }); } } test "parse commit" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); const head = try repo.getHead(); if (try repo.getObject(head)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); - switch (try o.parse(std.testing.allocator)) { + switch (try o.parse(alloc)) { .c => |c| { std.debug.print("commit:\n tree: {x}\n parent: {x}\n author: {s}\n committer: {s}\n message: {s}\n", .{ c.tree, c.parent, c.author, c.committer, c.message }); }, @@ -453,24 +476,32 @@ test "parse commit" { } test "get tree" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); if (try repo.getObject(0xceb2b2c62d6f8f3686dcacecd5be931839b02c77)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); // std.debug.print("tree({}): {any}\n", .{ o.kind, o.data }); } } test "parse tree" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); if (try repo.getObject(0xceb2b2c62d6f8f3686dcacecd5be931839b02c77)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); - switch (try o.parse(std.testing.allocator)) { + switch (try o.parse(alloc)) { .t => |t| { defer t.deinit(); for (t.items) |treeEntry| { @@ -483,7 +514,11 @@ test "parse tree" { } test "list commits" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); const head = try repo.getHead(); @@ -492,9 +527,9 @@ test "list commits" { for (0..3) |_| { if (try repo.getObject(id)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); - switch (try o.parse(std.testing.allocator)) { + switch (try o.parse(alloc)) { .c => |c| { std.debug.print("commit {x}:\n tree: {x}\n parent: {x}\n author: {s}\n committer: {s}\n message: {s}\n", .{ id, c.tree, c.parent, c.author, c.committer, c.message }); id = c.parent; @@ -506,21 +541,25 @@ test "list commits" { } test "list blobs" { - var repo = try Repo.open(std.testing.allocator, "../imgui/.git"); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); defer repo.close(); if (try repo.getObject(0xceb2b2c62d6f8f3686dcacecd5be931839b02c77)) |o| { - defer std.testing.allocator.free(o.data); + defer alloc.free(o.data); - switch (try o.parse(std.testing.allocator)) { + switch (try o.parse(alloc)) { .t => |t| { defer t.deinit(); for (t.items) |treeEntry| { if (try repo.getObject(treeEntry.id)) |bo| { - defer std.testing.allocator.free(bo.data); + defer alloc.free(bo.data); if (treeEntry.permissions.len == 6) { - std.debug.print("{s}: {s}\n", .{ treeEntry.name, bo.data[0..50] }); + std.debug.print("{s}: [{x} {}]{s}\n", .{ treeEntry.name, treeEntry.id, bo.data.len, bo.data[0..50] }); } else { std.debug.print("[{s}]\n", .{treeEntry.name}); } @@ -531,3 +570,30 @@ test "list blobs" { } } } + +test "basic frontend" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + + var repo = try Repo.open(alloc, "../imgui/.git"); + defer repo.close(); + + const head = try repo.getHead(); + + var id = head; + + for (0..3) |_| { + if (try repo.getObject(id)) |o| { + defer alloc.free(o.data); + + switch (try o.parse(alloc)) { + .c => |c| { + std.debug.print("commit {x}:\n tree: {x}\n parent: {x}\n author: {s}\n committer: {s}\n message: {s}\n", .{ id, c.tree, c.parent, c.author, c.committer, c.message }); + id = c.parent; + }, + else => {}, + } + } + } +}