forked from
anil.recoil.org/monopam
Monorepo management for opam overlays
1(** Monoverse operations.
2
3 Federated monorepo collaboration. Members are identified by handles and
4 validated against the registry. *)
5
6(** {1 Error Types} *)
7
8type error =
9 | Config_error of string (** Configuration loading/saving error *)
10 | Git_error of Git.error (** Git operation failed *)
11 | Registry_error of string (** Registry clone/pull/parse error *)
12 | Member_not_found of string (** Handle not in registry *)
13 | Workspace_exists of Fpath.t (** Workspace already initialized *)
14 | Not_a_workspace of Fpath.t (** Not a opamverse workspace *)
15 | Package_not_found of string * string (** Package not found in member's repo: (package, handle) *)
16 | Package_already_exists of string list (** Packages already exist in user's opam repo *)
17 | Opam_repo_error of Opam_repo.error (** Error reading/writing opam files *)
18
19val pp_error : error Fmt.t
20(** [pp_error] formats errors. *)
21
22val pp_error_with_hint : error Fmt.t
23(** [pp_error_with_hint] formats errors with a helpful hint for resolving them.
24*)
25
26val error_hint : error -> string option
27(** [error_hint e] returns a hint string for the given error, if available. *)
28
29(** {1 Status Types} *)
30
31type member_status = {
32 handle : string; (** Member's tangled handle *)
33 monorepo_url : string; (** Git URL of member's monorepo *)
34 local_path : Fpath.t; (** Local path under verse/ *)
35 cloned : bool; (** Whether the monorepo is cloned locally *)
36 clean : bool option; (** Whether the clone is clean (None if not cloned) *)
37 ahead_behind : Git.ahead_behind option;
38 (** Ahead/behind status (None if not cloned) *)
39}
40(** Status of a member's monorepo in the workspace. *)
41
42type status = {
43 config : Verse_config.t; (** Workspace configuration *)
44 registry : Verse_registry.t; (** Registry contents *)
45 tracked_members : member_status list; (** Status of tracked members *)
46}
47(** Workspace status. *)
48
49val pp_member_status : member_status Fmt.t
50(** [pp_member_status] formats a member's status. *)
51
52val pp_status : status Fmt.t
53(** [pp_status] formats workspace status. *)
54
55(** {1 Operations} *)
56
57val init :
58 proc:_ Eio.Process.mgr ->
59 fs:Eio.Fs.dir_ty Eio.Path.t ->
60 root:Fpath.t ->
61 handle:string ->
62 unit ->
63 (unit, error) result
64(** [init ~proc ~fs ~root ~handle ()] initializes a new opamverse workspace.
65
66 Creates the workspace structure:
67 - [root/.opamverse/config.toml]
68 - [root/.opamverse/registry/] (cloned registry)
69 - [root/mono/] (user's monorepo)
70 - [root/src/] (source checkouts)
71 - [root/verse/] (other users' monorepos)
72
73 The handle is validated against the registry.
74
75 @param proc Eio process manager
76 @param fs Eio filesystem
77 @param root Workspace root (must be absolute)
78 @param handle User's handle *)
79
80val status :
81 proc:_ Eio.Process.mgr ->
82 fs:Eio.Fs.dir_ty Eio.Path.t ->
83 config:Verse_config.t ->
84 unit ->
85 (status, error) result
86(** [status ~proc ~fs ~config ()] returns the workspace status.
87
88 Shows which members are tracked and the state of their local clones. *)
89
90val members :
91 proc:_ Eio.Process.mgr ->
92 fs:Eio.Fs.dir_ty Eio.Path.t ->
93 config:Verse_config.t ->
94 unit ->
95 (Verse_registry.member list, error) result
96(** [members ~proc ~fs ~config ()] returns all registry members.
97
98 Pulls the latest registry before returning the member list. *)
99
100val pull :
101 proc:_ Eio.Process.mgr ->
102 fs:Eio.Fs.dir_ty Eio.Path.t ->
103 config:Verse_config.t ->
104 ?handle:string ->
105 unit ->
106 (unit, error) result
107(** [pull ~proc ~fs ~config ?handle ()] syncs all registry members.
108
109 For each member in the registry, clones or pulls both their monorepo (to
110 [verse/<handle>/]) and their opam repo (to [verse/<handle>-opam/]).
111
112 If [handle] is specified, only syncs that specific member.
113
114 @param handle Optional specific member to sync *)
115
116val sync :
117 proc:_ Eio.Process.mgr ->
118 fs:Eio.Fs.dir_ty Eio.Path.t ->
119 config:Verse_config.t ->
120 unit ->
121 (unit, error) result
122(** [sync ~proc ~fs ~config ()] syncs the workspace.
123
124 Updates the registry and pulls updates for all tracked members. *)
125
126(** {1 Subtree Discovery} *)
127
128val scan_subtrees :
129 proc:_ Eio.Process.mgr ->
130 fs:Eio.Fs.dir_ty Eio.Path.t ->
131 Fpath.t ->
132 string list
133(** [scan_subtrees ~proc ~fs monorepo_path] returns a list of directory names
134 that look like subtrees in the given monorepo.
135
136 Filters out hidden directories, _build, node_modules, etc. *)
137
138val get_verse_subtrees :
139 proc:_ Eio.Process.mgr ->
140 fs:Eio.Fs.dir_ty Eio.Path.t ->
141 config:Verse_config.t ->
142 unit ->
143 (string, (string * Fpath.t) list) Hashtbl.t
144(** [get_verse_subtrees ~proc ~fs ~config ()] scans all tracked verse members
145 and returns a map from subtree name to list of (handle, monorepo_path)
146 pairs.
147
148 This allows finding which verse users have a particular repo. *)
149
150(** {1 Forking} *)
151
152(** Result of a fork operation. *)
153type fork_result = {
154 packages_forked : string list; (** Package names that were forked *)
155 source_handle : string; (** Handle of the verse member we forked from *)
156 fork_url : string; (** URL of the fork *)
157 upstream_url : string; (** Original dev-repo URL (upstream) *)
158 subtree_name : string; (** Name for the subtree directory (derived from fork URL) *)
159}
160
161val pp_fork_result : fork_result Fmt.t
162(** [pp_fork_result] formats a fork result. *)
163
164val fork :
165 proc:_ Eio.Process.mgr ->
166 fs:Eio.Fs.dir_ty Eio.Path.t ->
167 config:Verse_config.t ->
168 handle:string ->
169 package:string ->
170 fork_url:string ->
171 ?dry_run:bool ->
172 unit ->
173 (fork_result, error) result
174(** [fork ~proc ~fs ~config ~handle ~package ~fork_url ?dry_run ()] forks a
175 package from a verse member's opam repo into your workspace.
176
177 This looks up the package in the member's opam-repo (verse/<handle>-opam/),
178 finds all packages sharing the same dev-repo, and creates entries in your
179 opam-repo with the fork URL as the dev-repo.
180
181 After forking, run [monopam sync] to pull the fork into your monorepo.
182
183 @param proc Eio process manager
184 @param fs Eio filesystem
185 @param config Verse configuration
186 @param handle Verse member handle to fork from
187 @param package Package name to fork
188 @param fork_url Git URL of your fork
189 @param dry_run If true, show what would be done without making changes *)