authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-05-04 14:00:19 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-05-04 14:00:19 -07:00
log84501a5ed933e48a1f8255df1363e731cdf5c156
tree1b0671f24f5de3b61f57f8dc7b1c6c2d292633ff
parent8b1baaec1950e8f8da2035a843190b7d8fad3df7

add parseTreeDiff


2 files changed, 124 insertions(+), 0 deletions(-)

git.zig+123
...@@ -2,6 +2,7 @@ const std = @import("std");...@@ -2,6 +2,7 @@ const std = @import("std");
2const string = []const u8;2const string = []const u8;
3const top = @This();3const top = @This();
4const time = @import("time");4const time = @import("time");
5const extras = @import("extras");
56
6// 40 is length of sha1 hash7// 40 is length of sha1 hash
7pub const Id = *const [40]u8;8pub const Id = *const [40]u8;
...@@ -343,3 +344,125 @@ pub const TreeDiffMeta = struct {...@@ -343,3 +344,125 @@ pub const TreeDiffMeta = struct {
343 lines_added: u32,344 lines_added: u32,
344 lines_removed: u32,345 lines_removed: u32,
345};346};
347
348pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff {
349 var lineiter = std.mem.split(u8, input, "\n");
350 var overview = std.ArrayList(TreeDiff.StateLine).init(alloc);
351 var diffs = std.ArrayList(TreeDiff.Diff).init(alloc);
352
353 while (lineiter.next()) |lin| {
354 if (lin.len == 0) break;
355 std.debug.assert(lin[0] == ':');
356
357 // :100644 100644 c06b41d04c381f1841d445c0072219d9a7f57e17 e8f91cf7dd413ac65a362b0a170951033dba4762 M notes/all_packages.txt
358 var jter = std.mem.tokenize(u8, lin[1..], " ");
359 const before_mode = try parseTreeMode(jter.next().?);
360 const after_mode = try parseTreeMode(jter.next().?);
361
362 const before_tree = ensureObjId(TreeId, jter.next().?);
363 const after_tree = ensureObjId(TreeId, jter.next().?);
364
365 var kter = std.mem.split(u8, jter.next().?, "\t"); // why is there a tab here git. why?
366 const action_s = kter.next().?;
367
368 try overview.append(.{
369 .before = .{
370 .mode = before_mode,
371 .tree = before_tree,
372 },
373 .after = .{
374 .mode = after_mode,
375 .tree = after_tree,
376 },
377 .action = std.meta.stringToEnum(TreeDiff.Action, action_s).?,
378 .sub_path = kter.rest(),
379 });
380 }
381
382 // diff --git a/notes/all_packages.txt b/notes/all_packages.txt
383 // index c06b41d..e8f91cf 100644
384 // --- a/notes/all_packages.txt
385 // +++ b/notes/all_packages.txt
386 // @@ -89,3 +89,4 @@ freedesktop/xorg/libsm
387 // freedesktop/xorg/libxt
388 // freedesktop/xorg/libxmu
389 // ncompress
390 // +freedesktop/xorg/libxpm
391 std.debug.assert(std.mem.startsWith(u8, lineiter.next().?, "diff --git"));
392 blk: while (true) {
393 while (lineiter.next()) |lin| {
394 if (std.mem.startsWith(u8, lin, "index")) break;
395 }
396
397 const before_path_raw = lineiter.next().?;
398 const before_path = extras.trimPrefixEnsure(before_path_raw, "--- a/") orelse extras.trimPrefixEnsure(before_path_raw, "--- ").?;
399
400 const after_path_raw = lineiter.next().?;
401 const after_path = extras.trimPrefixEnsure(after_path_raw, "+++ b/") orelse extras.trimPrefixEnsure(after_path_raw, "+++ ").?;
402
403 const start_index = lineiter.index.?;
404
405 while (lineiter.next()) |lin| {
406 if (std.mem.startsWith(u8, lin, "diff --git")) {
407 const end_index = lineiter.index.? - lin.len - 2;
408 try diffs.append(.{
409 .before_path = before_path,
410 .after_path = after_path,
411 .content = input[start_index..end_index],
412 });
413 continue :blk;
414 }
415 }
416 try diffs.append(.{
417 .before_path = before_path,
418 .after_path = after_path,
419 .content = input[start_index..],
420 });
421 break :blk;
422 }
423
424 return TreeDiff{
425 .overview = overview.items,
426 .diffs = diffs.items,
427 };
428}
429
430pub const TreeDiff = struct {
431 overview: []const StateLine,
432 diffs: []const Diff,
433
434 pub const StateLine = struct {
435 before: State,
436 after: State,
437 action: Action,
438 sub_path: string,
439 };
440
441 pub const State = struct {
442 mode: Tree.Object.Mode,
443 tree: TreeId,
444 };
445
446 pub const Action = enum {
447 A, // Added
448 C, // Copied
449 D, // Deleted
450 M, // Modified
451 R, // Renamed
452 T, // type changed
453 U, // Unmerged
454 X, // Unknown
455 B, // Broken
456
457 pub fn toString(self: Action, alloc: std.mem.Allocator) !string {
458 _ = alloc;
459 return @tagName(self);
460 }
461 };
462
463 pub const Diff = struct {
464 before_path: string,
465 after_path: string,
466 content: string,
467 };
468};
zig.mod+1
...@@ -5,3 +5,4 @@ license: MIT...@@ -5,3 +5,4 @@ license: MIT
5description: Inspect into the depths of your .git folder purely from Zig5description: Inspect into the depths of your .git folder purely from Zig
6dependencies:6dependencies:
7 - src: git https://github.com/nektro/zig-time7 - src: git https://github.com/nektro/zig-time
8 - src: git https://github.com/nektro/zig-extras