| ... | @@ -2,6 +2,7 @@ const std = @import("std"); | ... | @@ -2,6 +2,7 @@ const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const top = @This(); | 3 | const top = @This(); |
| 4 | const time = @import("time"); | 4 | const time = @import("time"); |
| | 5 | const extras = @import("extras"); |
| 5 | | 6 | |
| 6 | // 40 is length of sha1 hash | 7 | // 40 is length of sha1 hash |
| 7 | pub const Id = *const [40]u8; | 8 | pub 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 | |
| | 348 | pub 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 | |
| | 430 | pub 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 | }; |