A monorepo management tool for the agentic ages
1(** Backend module signature for package managers.
2
3 Each backend (opam, cargo, etc.) implements this interface to provide
4 vendoring capabilities. *)
5
6(** {1 Types} *)
7
8type package_info = {
9 name : string;
10 url : string;
11 branch : string option; (** Branch/tag/ref to use *)
12}
13(** Information about a package to vendor. *)
14
15type add_result =
16 | Added of { name : string; sha : string }
17 | Already_exists of string
18 | Failed of { name : string; error : string }
19
20type update_result =
21 | Updated of { name : string; old_sha : string; new_sha : string }
22 | No_changes of string
23 | Update_failed of { name : string; error : string }
24
25(** {1 Backend Signature} *)
26
27module type S = sig
28 val name : string
29 (** Backend name, e.g. "opam", "cargo". *)
30
31 (** {2 Branch Naming} *)
32
33 val upstream_branch : string -> string
34 (** [upstream_branch pkg] returns branch name, e.g. "opam/upstream/astring". *)
35
36 val vendor_branch : string -> string
37 (** [vendor_branch pkg] returns branch name, e.g. "opam/vendor/astring". *)
38
39 val patches_branch : string -> string
40 (** [patches_branch pkg] returns branch name, e.g. "opam/patches/astring". *)
41
42 val vendor_path : string -> string
43 (** [vendor_path pkg] returns path prefix, e.g. "vendor/opam/astring". *)
44
45 (** {2 Worktree Kinds} *)
46
47 val upstream_kind : string -> Worktree.kind
48 val vendor_kind : string -> Worktree.kind
49 val patches_kind : string -> Worktree.kind
50
51 (** {2 Package Operations} *)
52
53 val add_package :
54 proc_mgr:Git.proc_mgr ->
55 root:Worktree.root ->
56 package_info ->
57 add_result
58 (** [add_package ~proc_mgr ~root info] vendors a single package.
59
60 1. Creates/updates opam/upstream/<pkg> from URL
61 2. Creates opam/vendor/<pkg> orphan with vendor/ prefix
62 3. Creates opam/patches/<pkg> from vendor *)
63
64 val update_package :
65 proc_mgr:Git.proc_mgr ->
66 root:Worktree.root ->
67 string ->
68 update_result
69 (** [update_package ~proc_mgr ~root name] updates a package from upstream.
70
71 1. Fetches latest into opam/upstream/<pkg>
72 2. Updates opam/vendor/<pkg> with new content
73 Does NOT rebase patches - that's a separate operation. *)
74
75 val list_packages :
76 proc_mgr:Git.proc_mgr ->
77 root:Worktree.root ->
78 string list
79 (** [list_packages ~proc_mgr root] returns all vendored package names. *)
80end
81
82(** {1 Merge Operations} *)
83
84(** These operations are backend-agnostic and work on any patches branch. *)
85
86let merge_to_project ~proc_mgr ~root ~project ~patches_branch =
87 let project_wt = Worktree.path root (Worktree.Project project) in
88 Git.merge_allow_unrelated ~proc_mgr ~cwd:project_wt
89 ~branch:patches_branch
90 ~message:(Printf.sprintf "Merge %s" patches_branch)
91
92let rebase_patches ~proc_mgr ~root ~patches_kind ~onto =
93 Worktree.ensure ~proc_mgr root patches_kind;
94 let patches_wt = Worktree.path root patches_kind in
95 let result = Git.rebase ~proc_mgr ~cwd:patches_wt ~onto in
96 Worktree.remove ~proc_mgr root patches_kind;
97 result