Monorepo management for opam overlays
0
fork

Configure Feed

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

Add orphaned package detection to opam sync

When syncing opam metadata, now detects packages that exist in the
opam-repo overlay but have no corresponding subtree in the monorepo.
These are reported as warnings with a suggestion to manually remove
them from opam-repo/packages/.

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

+42 -11
+33 -5
lib/monopam.ml
··· 1446 1446 synced : string list; (* packages that were updated *) 1447 1447 unchanged : string list; (* packages that were already in sync *) 1448 1448 missing : string list; (* packages where monorepo has no .opam file *) 1449 + orphaned : string list; (* packages in opam-repo but subtree missing from monorepo *) 1449 1450 } 1450 1451 1451 1452 let pp_opam_sync_result ppf r = 1452 - Fmt.pf ppf "Synced: %d, Unchanged: %d, Missing: %d" 1453 + Fmt.pf ppf "Synced: %d, Unchanged: %d, Missing: %d, Orphaned: %d" 1453 1454 (List.length r.synced) (List.length r.unchanged) (List.length r.missing) 1455 + (List.length r.orphaned) 1454 1456 1455 1457 (* Read file contents safely, returning None if file doesn't exist *) 1456 1458 let read_file_opt path = ··· 1517 1519 let synced = ref [] in 1518 1520 let unchanged = ref [] in 1519 1521 let missing = ref [] in 1522 + let orphaned = ref [] in 1523 + 1524 + (* Check each package *) 1520 1525 List.iter (fun pkg -> 1521 - match sync_opam_file ~proc ~fs ~config pkg with 1522 - | `Synced name -> synced := name :: !synced 1523 - | `Unchanged name -> unchanged := name :: !unchanged 1524 - | `Missing name -> missing := name :: !missing) 1526 + (* Check if the subtree exists in monorepo *) 1527 + let monorepo = Config.Paths.monorepo config in 1528 + let subtree_prefix = Package.subtree_prefix pkg in 1529 + let subtree_exists = Git.Subtree.exists ~fs ~repo:monorepo ~prefix:subtree_prefix in 1530 + 1531 + if not subtree_exists then 1532 + (* Subtree doesn't exist - package is orphaned in opam-repo *) 1533 + orphaned := Package.name pkg :: !orphaned 1534 + else 1535 + match sync_opam_file ~proc ~fs ~config pkg with 1536 + | `Synced name -> synced := name :: !synced 1537 + | `Unchanged name -> unchanged := name :: !unchanged 1538 + | `Missing name -> missing := name :: !missing) 1525 1539 pkgs; 1540 + 1526 1541 let result = { 1527 1542 synced = List.rev !synced; 1528 1543 unchanged = List.rev !unchanged; 1529 1544 missing = List.rev !missing; 1545 + orphaned = List.rev !orphaned; 1530 1546 } in 1547 + 1531 1548 (* Commit if there were changes *) 1532 1549 if result.synced <> [] then begin 1533 1550 let opam_repo = Config.Paths.opam_repo config in ··· 1542 1559 ignore (Eio.Process.await child)); 1543 1560 Log.app (fun m -> m "Committed opam sync: %s" msg) 1544 1561 end; 1562 + 1563 + (* Report orphaned packages *) 1564 + if result.orphaned <> [] then begin 1565 + Log.warn (fun m -> m "Found %d orphaned packages in opam-repo (subtree missing from monorepo):" 1566 + (List.length result.orphaned)); 1567 + List.iter (fun name -> 1568 + Log.warn (fun m -> m " %s" name)) 1569 + result.orphaned; 1570 + Log.warn (fun m -> m "To remove, delete from opam-repo/packages/ and commit.") 1571 + end; 1572 + 1545 1573 Log.app (fun m -> m "%a" pp_opam_sync_result result); 1546 1574 Ok result 1547 1575 end
+9 -6
lib/monopam.mli
··· 195 195 synced : string list; (** Packages that were updated *) 196 196 unchanged : string list; (** Packages that were already in sync *) 197 197 missing : string list; (** Packages where monorepo has no .opam file *) 198 + orphaned : string list; (** Packages in opam-repo but subtree missing from monorepo *) 198 199 } 199 200 200 201 val pp_opam_sync_result : opam_sync_result Fmt.t ··· 211 212 from monorepo subtrees to the opam-repo overlay. 212 213 213 214 For each package (or the specified package): 214 - 1. Reads the .opam file from the monorepo subtree 215 - 2. Compares with the opam-repo version 216 - 3. If different, copies monorepo → opam-repo (local always wins) 217 - 4. Stages and commits changes in opam-repo 215 + 1. Checks if the subtree exists in the monorepo 216 + 2. If subtree missing, reports as orphaned (needs manual removal) 217 + 3. Reads the .opam file from the monorepo subtree 218 + 4. Compares with the opam-repo version 219 + 5. If different, copies monorepo → opam-repo (local always wins) 220 + 6. Stages and commits changes in opam-repo 218 221 219 - This ensures that the opam overlay reflects any changes made to .opam 220 - files in the monorepo. 222 + Orphaned packages (in opam-repo but subtree missing from monorepo) are 223 + reported with a warning suggesting manual removal. 221 224 222 225 @param proc Eio process manager 223 226 @param fs Eio filesystem