╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ patch.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
502 const base_oid = (try target.readRef(io, .{ .kind = .head, .name = "master" })) orelse return error.NotFound; 503 const base_tree_oid = try commitTree(io, allocator, &target, &base_oid); 504 var source = try Repo.clone(io, allocator, upstream_path, source_path, source_path, null, .{}); 505 defer source.deinit(io, allocator); 506 const source_oid = blk: { 507 const file = try source.core.work_dir.createFile(io, "feature.zig", .{ .truncate = true }); 508 defer file.close(io); 509 try file.writeStreamingAll(io, "pub const answer = 42;\n"); 510 try source.add(io, allocator, &.{"feature.zig"}); 511 break :blk try source.commit(io, allocator, .{ .author = "alice <alice@example.test>", .message = "add feature", .timestamp = 2 }); 512 }; 513 const head_tree_oid = try commitTree(io, allocator, &source, &source_oid); 514 const first_patchrev_id = evt.EventWithId.randomId(prng.random()); 515 const first_patchrev_hex = std.fmt.bytesToHex(first_patchrev_id, .lower); 516 const first_entries = [_]evt.EventTreeEntry{ 517 .{ .tree = .{ .name = "base", .oid = &base_tree_oid } }, 518 .{ .tree = .{ .name = "head", .oid = &head_tree_oid } }, 519 }; 520 { 521 var draft = try Repo.open(io, allocator, .{ .path = draft_path }); 522 defer draft.deinit(io, allocator); 523 var arena = std.heap.ArenaAllocator.init(allocator); 524 defer arena.deinit(); 525 526 const initial_moment = try evt.currentMoment(repo_opts, &draft); 527 const initial_patch = (try evt.Patch.readById(Repo.DB, repo_opts.hash, initial_moment, &arena, &patch_id)) orelse return error.NotFound; 528 try std.testing.expect(!initial_patch.removed); 529 try std.testing.expectEqualStrings("add the answer", initial_patch.event.title); 530 try std.testing.expectEqual(null, initial_patch.event.patchrev_id); 531 try std.testing.expectEqual(null, try evt.PatchRev.readNewest(Repo.DB, repo_opts.hash, initial_moment, &arena)); 532 533 var source_moment = try source.core.latestMoment(); 534 const source_state = Repo.State(.read_only){ .core = &source.core, .extra = .{ .moment = &source_moment } }; 535 var objects = try obj.ObjectIterator(.xit, repo_opts).init(source_state, io, allocator, .{ .kind = .all }); 536 defer objects.deinit(); 537 try objects.include(&source_oid); 538 try draft.copyObjects(.xit, repo_opts, &objects, io, null); 539 try evt.consume(.fork, .xit, repo_opts, io, allocator, &draft, evt.events_ref, &.{ 540 .{ 541 .id = first_patchrev_hex, 542 .timestamp = 3, 543 .author = author, 544 .tree_entries = &first_entries, 545 .event = .{ .patchrev = .{ 546 .base_oid = &base_oid, 547 .source_oid = &source_oid, 548 .target_ref = "refs/heads/master", 549 .message = "add the answer", 550 } }, 551 }, 552 .{ 553 .id = patch_id_hex, 554 .timestamp = 3, 555 .author = author, 556 .event = .{ .patch = .{ 557 .title = "add the answer", 558 .tags = "enhancement", 559 .description = "adds a reusable answer constant", 560 .patchrev_id = first_patchrev_hex, 561 } }, 562 }, 563 }); 564 565 _ = arena.reset(.retain_capacity); 566 const moment = try evt.currentMoment(repo_opts, &draft); 567 const patch = (try evt.Patch.readById(Repo.DB, repo_opts.hash, moment, &arena, &patch_id)) orelse return error.NotFound; 568 try std.testing.expect(!patch.removed); 569 try std.testing.expectEqualStrings(&first_patchrev_hex, &(patch.event.patchrev_id orelse return error.NotFound)); 570 try std.testing.expect(null != try evt.PatchRev.readById(Repo.DB, repo_opts.hash, moment, &arena, &first_patchrev_id)); 571 } 572 try std.testing.expectError(error.NotFound, evt.currentMoment(repo_opts, &target)); 573 574 // 575 // publish the metadata and revision pointer 576 // 577 578 try fork.publish(repo_opts, io, allocator, &admin, &target, draft_path, .{ 579 .id = patch_id_hex, 580 .user_id = user_id, 581 .repo_id = repo_id, 582 .author = author, 583 .timestamp = 3, 584 }); 585 586 var arena = std.heap.ArenaAllocator.init(allocator); 587 defer arena.deinit(); 588 const moment = try evt.currentMoment(repo_opts, &target); 589 const patch = (try evt.Patch.readById(Repo.DB, repo_opts.hash, moment, &arena, &patch_id)) orelse return error.NotFound; 590 try std.testing.expectEqualStrings(&first_patchrev_hex, &(patch.event.patchrev_id orelse return error.NotFound)); 591 try std.testing.expectEqual(null, try evt.PatchRev.readById(Repo.DB, repo_opts.hash, moment, &arena, &first_patchrev_id)); 592 593 _ = arena.reset(.retain_capacity); 594 const admin_moment = try evt.currentMoment(evt.admin_repo_opts, &admin); 595 const published_fork = (try evt.Fork.readById(evt.AdminDB, evt.admin_repo_opts.hash, admin_moment, &arena, &patch_id)) orelse return error.NotFound; 596 try std.testing.expect(!published_fork.removed); 597 { 598 var draft = try Repo.open(io, allocator, .{ .path = draft_path }); 599 defer draft.deinit(io, allocator); 600 _ = arena.reset(.retain_capacity); 601 const draft_moment = try evt.currentMoment(repo_opts, &draft); 602 const removed = (try evt.Patch.readById(Repo.DB, repo_opts.hash, draft_moment, &arena, &patch_id)) orelse return error.NotFound; 603 try std.testing.expect(removed.removed); 604 const revision = (try evt.PatchRev.readById(Repo.DB, repo_opts.hash, draft_moment, &arena, &first_patchrev_id)) orelse return error.NotFound; 605 try std.testing.expectEqualStrings("refs/heads/master", revision.event.target_ref); 606 try std.testing.expectEqual(hash.hexLen(repo_opts.hash), revision.event_oid.len); 607 var event_oid: [hash.hexLen(repo_opts.hash)]u8 = undefined; 608 @memcpy(&event_oid, revision.event_oid); 609 var repo_moment = try draft.core.latestMoment(); 610 const state = Repo.State(.read_only){ .core = &draft.core, .extra = .{ .moment = &repo_moment } }; 611 var event_object = try obj.Object(.xit, repo_opts).initCommit(state, io, allocator, &event_oid); 612 defer event_object.deinit(); 613 const trees = try evt.PatchRev.readTrees(.xit, repo_opts, state, io, allocator, &event_object.content.commit.tree); 614 try std.testing.expectEqualStrings(revision.base_tree_oid, &trees.base); 615 try std.testing.expectEqualStrings(revision.head_tree_oid, &trees.head); 616 } 617 } 618