Monorepo management for opam overlays
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add --all flag to monopam verse add command

Add ability to add all registry members at once with `verse add --all`.
This iterates over all members in the opamverse registry, validates each
handle, and clones their monorepos to verse/<handle>/. Members already
tracked are skipped.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+96 -9
+34 -9
bin/main.ml
··· 528 528 in 529 529 Cmd.v info Term.(ret (const run $ logging_term)) 530 530 531 + let verse_add_all_arg = 532 + let doc = "Add all members from the registry." in 533 + Arg.(value & flag & info [ "all" ] ~doc) 534 + 531 535 let verse_add_cmd = 532 536 let doc = "Add a member to the workspace" in 533 537 let man = ··· 536 540 `P 537 541 "Adds a community member's monorepo to your workspace by cloning it \ 538 542 to the verse/<handle>/ directory."; 543 + `P 544 + "With --all, adds all members from the registry that are not already \ 545 + tracked in your workspace."; 539 546 `S "PROCESS"; 540 547 `P "The add command performs the following steps:"; 541 548 `I ("1.", "Validates the handle against the tangled network (AT Protocol)"); ··· 555 562 `S Manpage.s_examples; 556 563 `Pre "# Add a member\n\ 557 564 monopam verse add alice.bsky.social\n\n\ 565 + # Add all members from the registry\n\ 566 + monopam verse add --all\n\n\ 558 567 # Browse their code\n\ 559 568 ls verse/alice.bsky.social/\n\ 560 569 cd verse/alice.bsky.social && dune build"; ··· 565 574 ] 566 575 in 567 576 let info = Cmd.info "add" ~doc ~man in 568 - let run handle () = 577 + let run handle all () = 569 578 Eio_main.run @@ fun env -> 570 579 Eio.Switch.run @@ fun sw -> 571 580 with_verse_config env @@ fun config -> 572 581 let fs = Eio.Stdenv.fs env in 573 582 let proc = Eio.Stdenv.process_mgr env in 574 - match Monopam.Verse.add ~proc ~fs ~sw ~env ~config ~handle () with 575 - | Ok () -> 576 - Fmt.pr "Added %s to workspace.@." handle; 577 - `Ok () 578 - | Error e -> 579 - Fmt.epr "Error: %a@." Monopam.Verse.pp_error e; 580 - `Error (false, "add failed") 583 + match (handle, all) with 584 + | None, false -> 585 + Fmt.epr "Error: Either provide a HANDLE or use --all@."; 586 + `Error (true, "missing argument") 587 + | Some _, true -> 588 + Fmt.epr "Error: Cannot use --all with a specific handle@."; 589 + `Error (true, "conflicting arguments") 590 + | Some handle, false -> 591 + (match Monopam.Verse.add ~proc ~fs ~sw ~env ~config ~handle () with 592 + | Ok () -> 593 + Fmt.pr "Added %s to workspace.@." handle; 594 + `Ok () 595 + | Error e -> 596 + Fmt.epr "Error: %a@." Monopam.Verse.pp_error e; 597 + `Error (false, "add failed")) 598 + | None, true -> 599 + (match Monopam.Verse.add_all ~proc ~fs ~sw ~env ~config () with 600 + | Ok members -> 601 + Fmt.pr "Added %d members to workspace.@." (List.length members); 602 + `Ok () 603 + | Error e -> 604 + Fmt.epr "Error: %a@." Monopam.Verse.pp_error e; 605 + `Error (false, "add --all failed")) 581 606 in 582 - Cmd.v info Term.(ret (const run $ verse_handle_pos_arg $ logging_term)) 607 + Cmd.v info Term.(ret (const run $ verse_handle_opt_pos_arg $ verse_add_all_arg $ logging_term)) 583 608 584 609 let verse_remove_cmd = 585 610 let doc = "Remove a member from the workspace" in
+47
lib/verse.ml
··· 310 310 Ok () 311 311 end 312 312 313 + let add_all ~proc ~fs ~sw ~env ~config () = 314 + Logs.info (fun m -> m "Adding all registry members"); 315 + (* Load registry *) 316 + match Verse_registry.clone_or_pull ~proc ~fs ~config () with 317 + | Error msg -> Error (Registry_error msg) 318 + | Ok registry -> 319 + (* Get already tracked handles to skip them *) 320 + let tracked = get_tracked_handles ~fs config in 321 + let tracked_set = List.fold_left (fun acc h -> 322 + String.Map.add h () acc) String.Map.empty tracked in 323 + (* Ensure verse directory exists *) 324 + let verse_dir = Verse_config.verse_path config in 325 + ensure_dir ~fs verse_dir; 326 + (* Add each member that isn't already tracked *) 327 + let added = ref [] in 328 + let errors = 329 + List.filter_map 330 + (fun (member : Verse_registry.member) -> 331 + let handle = member.handle in 332 + if String.Map.mem handle tracked_set then begin 333 + Logs.info (fun m -> m "Skipping %s (already tracked)" handle); 334 + None 335 + end 336 + else begin 337 + (* Validate handle *) 338 + match validate_handle ~sw ~env handle with 339 + | Error e -> 340 + Logs.warn (fun m -> m "Skipping %s: %a" handle pp_error e); 341 + Some (Fmt.str "%s: %a" handle pp_error e) 342 + | Ok () -> 343 + let local_path = Fpath.(verse_dir / handle) in 344 + let url = Uri.of_string member.monorepo in 345 + Logs.info (fun m -> m "Cloning %s from %s" handle member.monorepo); 346 + match Git.clone ~proc ~fs ~url ~branch:Verse_config.default_branch local_path with 347 + | Error e -> 348 + Logs.warn (fun m -> m "Failed to clone %s: %a" handle Git.pp_error e); 349 + Some (Fmt.str "%s: %a" handle Git.pp_error e) 350 + | Ok () -> 351 + Logs.info (fun m -> m "Cloned %s" handle); 352 + added := member :: !added; 353 + None 354 + end) 355 + registry.members 356 + in 357 + if errors = [] then Ok (List.rev !added) 358 + else Error (Git_error (Git.Io_error (String.concat "; " errors))) 359 + 313 360 let pull ~proc ~fs ~config ?handle () = 314 361 match handle with 315 362 | Some h ->
+15
lib/verse.mli
··· 108 108 109 109 @param handle Tangled handle of the member to add *) 110 110 111 + val add_all : 112 + proc:_ Eio.Process.mgr -> 113 + fs:Eio.Fs.dir_ty Eio.Path.t -> 114 + sw:Eio.Switch.t -> 115 + env:< clock : _ Eio.Time.clock ; net : _ Eio.Net.t ; fs : Eio.Fs.dir_ty Eio.Path.t ; .. > -> 116 + config:Verse_config.t -> 117 + unit -> 118 + (Verse_registry.member list, error) result 119 + (** [add_all ~proc ~fs ~sw ~env ~config ()] adds all registry members to the workspace. 120 + 121 + Iterates over all members in the registry and clones their monorepos to 122 + [verse/<handle>/]. Members already tracked are skipped. 123 + 124 + Returns the list of members that were added. *) 125 + 111 126 val remove : 112 127 fs:Eio.Fs.dir_ty Eio.Path.t -> 113 128 config:Verse_config.t ->