forked from
anil.recoil.org/monopam
Monorepo management for opam overlays
1(** Transform dune-generated opam files for opam-repo overlay. *)
2
3(** Remove the "generated by dune" comment from the first line *)
4let strip_dune_comment content =
5 let lines = String.split_on_char '\n' content in
6 match lines with
7 | first :: rest
8 when String.starts_with ~prefix:"# This file is generated by dune"
9 (String.trim first) ->
10 String.concat "\n" rest
11 | _ -> content
12
13(** Remove existing dev-repo line if present *)
14let remove_dev_repo_line content =
15 let lines = String.split_on_char '\n' content in
16 let lines =
17 List.filter
18 (fun line ->
19 let trimmed = String.trim line in
20 not (String.starts_with ~prefix:"dev-repo:" trimmed))
21 lines
22 in
23 String.concat "\n" lines
24
25(** Remove existing url { ... } section if present *)
26let remove_url_section content =
27 let lines = String.split_on_char '\n' content in
28 let rec process lines in_url_block acc =
29 match lines with
30 | [] -> List.rev acc
31 | line :: rest ->
32 let trimmed = String.trim line in
33 if in_url_block then
34 (* Inside url { ... }, skip until we see } *)
35 if String.starts_with ~prefix:"}" trimmed then
36 process rest false acc
37 else process rest true acc
38 else if trimmed = "url {" || String.starts_with ~prefix:"url {" trimmed
39 then
40 (* Start of url block *)
41 if String.ends_with ~suffix:"}" trimmed then
42 (* Single-line url block, skip it *)
43 process rest false acc
44 else process rest true acc
45 else process rest false (line :: acc)
46 in
47 String.concat "\n" (process lines false [])
48
49(** Trim trailing blank lines and ensure single trailing newline *)
50let normalize_ending content =
51 let lines = String.split_on_char '\n' content in
52 let rec trim_trailing = function
53 | [] -> []
54 | [ "" ] -> []
55 | "" :: rest -> (
56 match trim_trailing rest with [] -> [] | trimmed -> "" :: trimmed)
57 | x :: rest -> x :: trim_trailing rest
58 in
59 let lines = List.rev (trim_trailing (List.rev lines)) in
60 String.concat "\n" lines
61
62let transform ~content ~dev_repo ~url_src =
63 (* Step 1: Strip the dune comment *)
64 let content = strip_dune_comment content in
65
66 (* Step 2: Remove any existing dev-repo and url sections *)
67 let content = remove_dev_repo_line content in
68 let content = remove_url_section content in
69
70 (* Step 3: Normalize ending *)
71 let content = normalize_ending content in
72
73 (* Step 4: Append dev-repo and url section *)
74 let dev_repo_line = Printf.sprintf {|dev-repo: "%s"|} dev_repo in
75 let url_section =
76 Printf.sprintf "url {\n src: \"%s\"\n}" url_src
77 in
78 content ^ "\n" ^ dev_repo_line ^ "\n" ^ url_section ^ "\n"