Monorepo management for opam overlays
0
fork

Configure Feed

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

fix(monopam): use sources.toml for opam-repo URLs and fix tangled format

- opam_sync: delegate derive_urls to Pkg.derive_dev_repo so sources.toml
overrides are respected (fixes memtrace getting github URLs in opam-repo)
- dune_project: update tangled URL format from tangled.sh/@host/repo.git
to tangled.org/host/repo to match current API
- pkg: expose derive_dev_repo in .mli
- Add 35 new tests for derive_dev_repo priority and dune-project URL generation

+533 -14
+1 -2
lib/dune_project.ml
··· 168 168 | Some (Gitlab { user; repo }) -> 169 169 Ok (Fmt.str "git+https://gitlab.com/%s/%s.git" user repo) 170 170 | Some (Tangled { host; repo }) -> 171 - (* Tangled sources: https://tangled.sh/@handle/repo *) 172 - Ok (Fmt.str "git+https://tangled.sh/@%s/%s.git" host repo) 171 + Ok (Fmt.str "git+https://tangled.org/%s/%s" host repo) 173 172 | Some (Uri { url; _ }) -> Ok (normalize_git_url (ensure_git_suffix url)) 174 173 | None -> ( 175 174 match t.homepage with
+3 -2
lib/dune_project.mli
··· 7 7 type source_info = 8 8 | Github of { user : string; repo : string } 9 9 | Gitlab of { user : string; repo : string } 10 - | Tangled of { host : string; repo : string } (** tangled.sh style sources *) 10 + | Tangled of { host : string; repo : string } 11 + (** tangled.org style sources *) 11 12 | Uri of { url : string; branch : string option } 12 13 13 14 type t = { ··· 33 34 URL derivation logic: 34 35 - [Github \{user; repo\}] -> ["git+https://github.com/user/repo.git"] 35 36 - [Gitlab \{user; repo\}] -> ["git+https://gitlab.com/user/repo.git"] 36 - - [Tangled \{host; repo\}] -> ["git+https://tangled.sh/@host/repo.git"] 37 + - [Tangled \{host; repo\}] -> ["git+https://tangled.org/host/repo"] 37 38 - [Uri \{url; _\}] -> url normalized with [git+] prefix 38 39 - No source but homepage present -> homepage normalized with [git+] prefix 39 40 - Neither source nor homepage -> [Error]. *)
+5 -9
lib/opam_sync.ml
··· 229 229 230 230 (** {1 CWD-based Export} *) 231 231 232 - (** Derive dev_repo and url_src from a dune-project and sources registry. *) 232 + (** Derive dev_repo and url_src from a dune-project and sources registry. 233 + Priority: sources.toml override > dune-project source > default_url_base *) 233 234 let derive_urls ~sources ~subtree dune_proj = 234 - match 235 - (Dune_project.dev_repo_url dune_proj, Dune_project.url_with_branch dune_proj) 236 - with 237 - | Ok dr, Ok us -> (dr, us) 238 - | _ -> ( 239 - match Sources_registry.derive_url sources ~subtree with 240 - | Some url -> (url, url ^ "#main") 241 - | None -> ("", "")) 235 + match Pkg.derive_dev_repo ~sources ~subtree dune_proj with 236 + | Some (dev_repo, url_src) -> (dev_repo, url_src) 237 + | None -> ("", "") 242 238 243 239 (** Load opam packages from a directory given metadata. *) 244 240 let load_opam_pkgs dir_eio ~subtree ~dev_repo ~url_src =
+8
lib/pkg.mli
··· 34 34 val opam_content : t -> string 35 35 (** Raw content of the opam file. *) 36 36 37 + val derive_dev_repo : 38 + sources:Sources_registry.t -> 39 + subtree:string -> 40 + Dune_project.t -> 41 + (string * string) option 42 + (** [derive_dev_repo ~sources ~subtree dune_proj] derives [(dev_repo, url_src)] 43 + from sources.toml, dune-project, or default_url_base (in priority order). *) 44 + 37 45 val discover : 38 46 fs:Eio.Fs.dir_ty Eio.Path.t -> 39 47 config:Config.t ->
+3
test/publish.t
··· 124 124 125 125 $ publish --dry-run --opam-repo "$TROOT/ws-opam-repo" --no-checkouts 126 126 Dry run: publishing from $TESTCASE_ROOT/workspace to $TESTCASE_ROOT/ws-opam-repo 127 + monopam: [WARNING] Cannot derive dev-repo for workspace (no source in dune-project or sources.toml) 127 128 Synced 3 packages: 128 129 root 129 130 mylib ··· 134 135 135 136 $ publish my-lib --dry-run --opam-repo "$TROOT/ws-opam-repo" --no-checkouts 136 137 Dry run: publishing from $TESTCASE_ROOT/workspace to $TESTCASE_ROOT/ws-opam-repo 138 + monopam: [WARNING] Cannot derive dev-repo for workspace (no source in dune-project or sources.toml) 137 139 Synced 1 package: 138 140 mylib 139 141 ··· 142 144 143 145 $ publish mylib --dry-run --opam-repo "$TROOT/ws-opam-repo" --no-checkouts 144 146 Dry run: publishing from $TESTCASE_ROOT/workspace to $TESTCASE_ROOT/ws-opam-repo 147 + monopam: [WARNING] Cannot derive dev-repo for workspace (no source in dune-project or sources.toml) 145 148 Synced 1 package: 146 149 mylib 147 150
+269 -1
test/test_dune_project.ml
··· 1 1 (* Tests for dune_project *) 2 2 3 - let suite = ("dune_project", []) 3 + module DP = Monopam.Dune_project 4 + 5 + let check_ok msg expected result = 6 + match result with 7 + | Ok v -> Alcotest.(check string) msg expected v 8 + | Error e -> Alcotest.failf "%s: unexpected error: %s" msg e 9 + 10 + let check_error msg result = 11 + match result with 12 + | Ok v -> Alcotest.failf "%s: expected error, got %s" msg v 13 + | Error _ -> () 14 + 15 + (* {1 Parsing} *) 16 + 17 + let test_parse_minimal () = 18 + let content = {|(lang dune 3.21) 19 + (name my-lib)|} in 20 + match DP.parse content with 21 + | Ok t -> 22 + Alcotest.(check string) "name" "my-lib" t.name; 23 + Alcotest.(check (option reject)) "no source" None t.source 24 + | Error e -> Alcotest.failf "parse failed: %s" e 25 + 26 + let test_parse_github () = 27 + let content = {|(lang dune 3.21) 28 + (name eio) 29 + (source (github ocaml/eio))|} in 30 + match DP.parse content with 31 + | Ok t -> ( 32 + Alcotest.(check string) "name" "eio" t.name; 33 + match t.source with 34 + | Some (Github { user; repo }) -> 35 + Alcotest.(check string) "user" "ocaml" user; 36 + Alcotest.(check string) "repo" "eio" repo 37 + | _ -> Alcotest.fail "expected Github source") 38 + | Error e -> Alcotest.failf "parse failed: %s" e 39 + 40 + let test_parse_gitlab () = 41 + let content = {|(lang dune 3.21) 42 + (name lib) 43 + (source (gitlab org/lib))|} in 44 + match DP.parse content with 45 + | Ok t -> ( 46 + match t.source with 47 + | Some (Gitlab { user; repo }) -> 48 + Alcotest.(check string) "user" "org" user; 49 + Alcotest.(check string) "repo" "lib" repo 50 + | _ -> Alcotest.fail "expected Gitlab source") 51 + | Error e -> Alcotest.failf "parse failed: %s" e 52 + 53 + let test_parse_tangled () = 54 + let content = 55 + {|(lang dune 3.21) 56 + (name ocaml-git) 57 + (source (tangled gazagnaire.org/ocaml-git))|} 58 + in 59 + match DP.parse content with 60 + | Ok t -> ( 61 + match t.source with 62 + | Some (Tangled { host; repo }) -> 63 + Alcotest.(check string) "host" "gazagnaire.org" host; 64 + Alcotest.(check string) "repo" "ocaml-git" repo 65 + | _ -> Alcotest.fail "expected Tangled source") 66 + | Error e -> Alcotest.failf "parse failed: %s" e 67 + 68 + let test_parse_uri () = 69 + let content = 70 + {|(lang dune 3.21) 71 + (name foo) 72 + (source (uri https://example.com/foo))|} 73 + in 74 + match DP.parse content with 75 + | Ok t -> ( 76 + match t.source with 77 + | Some (Uri { url; branch }) -> 78 + Alcotest.(check string) "url" "https://example.com/foo" url; 79 + Alcotest.(check (option string)) "no branch" None branch 80 + | _ -> Alcotest.fail "expected Uri source") 81 + | Error e -> Alcotest.failf "parse failed: %s" e 82 + 83 + let test_parse_uri_with_branch () = 84 + let content = 85 + {|(lang dune 3.21) 86 + (name foo) 87 + (source (uri https://example.com/foo#develop))|} 88 + in 89 + match DP.parse content with 90 + | Ok t -> ( 91 + match t.source with 92 + | Some (Uri { url; branch }) -> 93 + Alcotest.(check string) "url" "https://example.com/foo" url; 94 + Alcotest.(check (option string)) "branch" (Some "develop") branch 95 + | _ -> Alcotest.fail "expected Uri source") 96 + | Error e -> Alcotest.failf "parse failed: %s" e 97 + 98 + let test_parse_packages () = 99 + let content = 100 + {|(lang dune 3.21) 101 + (name foo) 102 + (package (name foo) (synopsis "Foo")) 103 + (package (name foo-unix) (synopsis "Foo Unix"))|} 104 + in 105 + match DP.parse content with 106 + | Ok t -> 107 + Alcotest.(check (list string)) "packages" [ "foo"; "foo-unix" ] t.packages 108 + | Error e -> Alcotest.failf "parse failed: %s" e 109 + 110 + let test_parse_homepage () = 111 + let content = 112 + {|(lang dune 3.21) 113 + (name foo) 114 + (homepage https://example.com/foo)|} 115 + in 116 + match DP.parse content with 117 + | Ok t -> 118 + Alcotest.(check (option string)) 119 + "homepage" (Some "https://example.com/foo") t.homepage 120 + | Error e -> Alcotest.failf "parse failed: %s" e 121 + 122 + (* {1 dev_repo_url} *) 123 + 124 + let test_dev_repo_github () = 125 + let t : DP.t = 126 + { 127 + name = "eio"; 128 + source = Some (Github { user = "ocaml"; repo = "eio" }); 129 + homepage = None; 130 + packages = [ "eio" ]; 131 + } 132 + in 133 + check_ok "github dev-repo" "git+https://github.com/ocaml/eio.git" 134 + (DP.dev_repo_url t) 135 + 136 + let test_dev_repo_gitlab () = 137 + let t : DP.t = 138 + { 139 + name = "lib"; 140 + source = Some (Gitlab { user = "org"; repo = "lib" }); 141 + homepage = None; 142 + packages = [ "lib" ]; 143 + } 144 + in 145 + check_ok "gitlab dev-repo" "git+https://gitlab.com/org/lib.git" 146 + (DP.dev_repo_url t) 147 + 148 + let test_dev_repo_tangled () = 149 + let t : DP.t = 150 + { 151 + name = "ocaml-git"; 152 + source = Some (Tangled { host = "gazagnaire.org"; repo = "ocaml-git" }); 153 + homepage = None; 154 + packages = [ "git" ]; 155 + } 156 + in 157 + check_ok "tangled dev-repo" "git+https://tangled.org/gazagnaire.org/ocaml-git" 158 + (DP.dev_repo_url t) 159 + 160 + let test_dev_repo_uri () = 161 + let t : DP.t = 162 + { 163 + name = "foo"; 164 + source = Some (Uri { url = "https://example.com/foo"; branch = None }); 165 + homepage = None; 166 + packages = [ "foo" ]; 167 + } 168 + in 169 + check_ok "uri dev-repo" "git+https://example.com/foo.git" (DP.dev_repo_url t) 170 + 171 + let test_dev_repo_uri_already_git () = 172 + let t : DP.t = 173 + { 174 + name = "foo"; 175 + source = Some (Uri { url = "https://example.com/foo.git"; branch = None }); 176 + homepage = None; 177 + packages = [ "foo" ]; 178 + } 179 + in 180 + check_ok "uri dev-repo no double .git" "git+https://example.com/foo.git" 181 + (DP.dev_repo_url t) 182 + 183 + let test_dev_repo_homepage_fallback () = 184 + let t : DP.t = 185 + { 186 + name = "foo"; 187 + source = None; 188 + homepage = Some "https://example.com/foo"; 189 + packages = [ "foo" ]; 190 + } 191 + in 192 + check_ok "homepage fallback" "git+https://example.com/foo.git" 193 + (DP.dev_repo_url t) 194 + 195 + let test_dev_repo_no_source () = 196 + let t : DP.t = 197 + { name = "foo"; source = None; homepage = None; packages = [ "foo" ] } 198 + in 199 + check_error "no source or homepage" (DP.dev_repo_url t) 200 + 201 + (* {1 url_with_branch} *) 202 + 203 + let test_url_with_branch_default () = 204 + let t : DP.t = 205 + { 206 + name = "eio"; 207 + source = Some (Github { user = "ocaml"; repo = "eio" }); 208 + homepage = None; 209 + packages = [ "eio" ]; 210 + } 211 + in 212 + check_ok "default branch is main" "git+https://github.com/ocaml/eio.git#main" 213 + (DP.url_with_branch t) 214 + 215 + let test_url_with_branch_explicit () = 216 + let t : DP.t = 217 + { 218 + name = "foo"; 219 + source = 220 + Some (Uri { url = "https://example.com/foo"; branch = Some "develop" }); 221 + homepage = None; 222 + packages = [ "foo" ]; 223 + } 224 + in 225 + check_ok "explicit branch" "git+https://example.com/foo.git#develop" 226 + (DP.url_with_branch t) 227 + 228 + let test_url_with_branch_tangled () = 229 + let t : DP.t = 230 + { 231 + name = "git"; 232 + source = Some (Tangled { host = "gazagnaire.org"; repo = "ocaml-git" }); 233 + homepage = None; 234 + packages = [ "git" ]; 235 + } 236 + in 237 + check_ok "tangled url with branch" 238 + "git+https://tangled.org/gazagnaire.org/ocaml-git#main" 239 + (DP.url_with_branch t) 240 + 241 + let suite = 242 + ( "dune_project", 243 + [ 244 + (* parsing *) 245 + Alcotest.test_case "parse minimal" `Quick test_parse_minimal; 246 + Alcotest.test_case "parse github" `Quick test_parse_github; 247 + Alcotest.test_case "parse gitlab" `Quick test_parse_gitlab; 248 + Alcotest.test_case "parse tangled" `Quick test_parse_tangled; 249 + Alcotest.test_case "parse uri" `Quick test_parse_uri; 250 + Alcotest.test_case "parse uri with branch" `Quick 251 + test_parse_uri_with_branch; 252 + Alcotest.test_case "parse packages" `Quick test_parse_packages; 253 + Alcotest.test_case "parse homepage" `Quick test_parse_homepage; 254 + (* dev_repo_url *) 255 + Alcotest.test_case "dev_repo github" `Quick test_dev_repo_github; 256 + Alcotest.test_case "dev_repo gitlab" `Quick test_dev_repo_gitlab; 257 + Alcotest.test_case "dev_repo tangled" `Quick test_dev_repo_tangled; 258 + Alcotest.test_case "dev_repo uri" `Quick test_dev_repo_uri; 259 + Alcotest.test_case "dev_repo uri no double .git" `Quick 260 + test_dev_repo_uri_already_git; 261 + Alcotest.test_case "dev_repo homepage fallback" `Quick 262 + test_dev_repo_homepage_fallback; 263 + Alcotest.test_case "dev_repo no source" `Quick test_dev_repo_no_source; 264 + (* url_with_branch *) 265 + Alcotest.test_case "url_with_branch default" `Quick 266 + test_url_with_branch_default; 267 + Alcotest.test_case "url_with_branch explicit" `Quick 268 + test_url_with_branch_explicit; 269 + Alcotest.test_case "url_with_branch tangled" `Quick 270 + test_url_with_branch_tangled; 271 + ] )
+244
test/test_pkg.ml
··· 1 1 (* Tests for Pkg module *) 2 2 3 3 module Pkg = Monopam.Pkg 4 + module SR = Monopam.Sources_registry 5 + module DP = Monopam.Dune_project 4 6 5 7 let test_matches_by_pkg_name () = 6 8 let pkg = ··· 25 27 in 26 28 Alcotest.(check bool) "no match" false (Pkg.matches_name "other" pkg) 27 29 30 + (* Helper to build a minimal dune-project *) 31 + let dune_proj ?source ?homepage () : DP.t = 32 + { name = "test"; source; homepage; packages = [ "test" ] } 33 + 34 + (* Helper to build a sources_registry entry *) 35 + let sr_entry ?(upstream = None) ?(branch = None) ?(reason = None) 36 + ?(entry_origin = None) ?(mono = false) ?(ref_ = None) source = 37 + SR.{ source; upstream; branch; reason; origin = entry_origin; mono; ref_ } 38 + 39 + let check_dev_repo msg expected result = 40 + Alcotest.(check (option (pair string string))) msg expected result 41 + 42 + (* {1 derive_dev_repo: sources.toml override (highest priority)} *) 43 + 44 + let test_derive_sources_override () = 45 + let sources = 46 + SR.add SR.empty ~subtree:"memtrace" 47 + (sr_entry "git@git.recoil.org:gazagnaire.org/memtrace") 48 + in 49 + let dp = 50 + dune_proj ~source:(Github { user = "janestreet"; repo = "memtrace" }) () 51 + in 52 + check_dev_repo "sources.toml wins over dune-project" 53 + (Some 54 + ( "git@git.recoil.org:gazagnaire.org/memtrace", 55 + "git@git.recoil.org:gazagnaire.org/memtrace#main" )) 56 + (Pkg.derive_dev_repo ~sources ~subtree:"memtrace" dp) 57 + 58 + let test_derive_sources_override_with_branch () = 59 + let sources = 60 + SR.add SR.empty ~subtree:"memtrace" 61 + (sr_entry ~branch:(Some "master") 62 + "git@git.recoil.org:gazagnaire.org/memtrace") 63 + in 64 + let dp = dune_proj () in 65 + check_dev_repo "sources.toml branch used" 66 + (Some 67 + ( "git@git.recoil.org:gazagnaire.org/memtrace", 68 + "git@git.recoil.org:gazagnaire.org/memtrace#master" )) 69 + (Pkg.derive_dev_repo ~sources ~subtree:"memtrace" dp) 70 + 71 + let test_derive_sources_override_branch_from_dune () = 72 + let sources = 73 + SR.add SR.empty ~subtree:"foo" (sr_entry "git+https://example.com/foo") 74 + in 75 + let dp = 76 + dune_proj 77 + ~source:(Uri { url = "https://example.com/old"; branch = Some "develop" }) 78 + () 79 + in 80 + check_dev_repo "branch falls back to dune-project source" 81 + (Some ("git+https://example.com/foo", "git+https://example.com/foo#develop")) 82 + (Pkg.derive_dev_repo ~sources ~subtree:"foo" dp) 83 + 84 + let test_derive_sources_override_no_branch () = 85 + let sources = 86 + SR.add SR.empty ~subtree:"foo" (sr_entry "git+https://example.com/foo") 87 + in 88 + let dp = dune_proj () in 89 + check_dev_repo "no branch defaults to main" 90 + (Some ("git+https://example.com/foo", "git+https://example.com/foo#main")) 91 + (Pkg.derive_dev_repo ~sources ~subtree:"foo" dp) 92 + 93 + (* {1 derive_dev_repo: dune-project fallback (second priority)} *) 94 + 95 + let test_derive_from_github () = 96 + let dp = dune_proj ~source:(Github { user = "ocaml"; repo = "eio" }) () in 97 + check_dev_repo "github source" 98 + (Some 99 + ( "git+https://github.com/ocaml/eio.git", 100 + "git+https://github.com/ocaml/eio.git#main" )) 101 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"eio" dp) 102 + 103 + let test_derive_from_gitlab () = 104 + let dp = dune_proj ~source:(Gitlab { user = "org"; repo = "lib" }) () in 105 + check_dev_repo "gitlab source" 106 + (Some 107 + ( "git+https://gitlab.com/org/lib.git", 108 + "git+https://gitlab.com/org/lib.git#main" )) 109 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"lib" dp) 110 + 111 + let test_derive_from_tangled () = 112 + let dp = 113 + dune_proj 114 + ~source:(Tangled { host = "gazagnaire.org"; repo = "ocaml-git" }) 115 + () 116 + in 117 + check_dev_repo "tangled source" 118 + (Some 119 + ( "git+https://tangled.org/gazagnaire.org/ocaml-git", 120 + "git+https://tangled.org/gazagnaire.org/ocaml-git#main" )) 121 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"ocaml-git" dp) 122 + 123 + let test_derive_from_uri () = 124 + let dp = 125 + dune_proj 126 + ~source:(Uri { url = "https://example.com/repo"; branch = Some "dev" }) 127 + () 128 + in 129 + check_dev_repo "uri source with branch" 130 + (Some 131 + ( "git+https://example.com/repo.git", 132 + "git+https://example.com/repo.git#dev" )) 133 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"repo" dp) 134 + 135 + let test_derive_from_uri_no_branch () = 136 + let dp = 137 + dune_proj 138 + ~source:(Uri { url = "https://example.com/repo"; branch = None }) 139 + () 140 + in 141 + check_dev_repo "uri source defaults to #main" 142 + (Some 143 + ( "git+https://example.com/repo.git", 144 + "git+https://example.com/repo.git#main" )) 145 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"repo" dp) 146 + 147 + (* {1 derive_dev_repo: default_url_base / origin fallback (third priority)} *) 148 + 149 + let test_derive_from_origin () = 150 + let sources = SR.with_origin SR.empty "git+https://tangled.org/user" in 151 + let dp = dune_proj () in 152 + check_dev_repo "origin used when no source entry or dune-project source" 153 + (Some 154 + ( "git+https://tangled.org/user/test-subtree", 155 + "git+https://tangled.org/user/test-subtree#main" )) 156 + (Pkg.derive_dev_repo ~sources ~subtree:"test-subtree" dp) 157 + 158 + let test_derive_from_origin_trailing_slash () = 159 + let sources = SR.with_origin SR.empty "git+https://tangled.org/user/" in 160 + let dp = dune_proj () in 161 + check_dev_repo "origin trailing slash stripped" 162 + (Some 163 + ( "git+https://tangled.org/user/foo", 164 + "git+https://tangled.org/user/foo#main" )) 165 + (Pkg.derive_dev_repo ~sources ~subtree:"foo" dp) 166 + 167 + (* {1 derive_dev_repo: no source available} *) 168 + 169 + let test_derive_none () = 170 + let dp = dune_proj () in 171 + check_dev_repo "no sources, no dune source, no origin" None 172 + (Pkg.derive_dev_repo ~sources:SR.empty ~subtree:"orphan" dp) 173 + 174 + (* {1 derive_dev_repo: priority ordering} *) 175 + 176 + let test_derive_sources_wins_over_dune () = 177 + let sources = 178 + SR.add SR.empty ~subtree:"pkg" (sr_entry "git@git.recoil.org:user/pkg") 179 + in 180 + let dp = dune_proj ~source:(Github { user = "upstream"; repo = "pkg" }) () in 181 + check_dev_repo "sources.toml takes priority over github dune-project" 182 + (Some ("git@git.recoil.org:user/pkg", "git@git.recoil.org:user/pkg#main")) 183 + (Pkg.derive_dev_repo ~sources ~subtree:"pkg" dp) 184 + 185 + let test_derive_dune_wins_over_origin () = 186 + let sources = SR.with_origin SR.empty "git+https://tangled.org/user" in 187 + let dp = dune_proj ~source:(Github { user = "ocaml"; repo = "eio" }) () in 188 + check_dev_repo "dune-project wins over origin" 189 + (Some 190 + ( "git+https://github.com/ocaml/eio.git", 191 + "git+https://github.com/ocaml/eio.git#main" )) 192 + (Pkg.derive_dev_repo ~sources ~subtree:"eio" dp) 193 + 194 + let test_derive_sources_wins_over_origin () = 195 + let sources = 196 + SR.with_origin SR.empty "git+https://tangled.org/user" |> fun s -> 197 + SR.add s ~subtree:"pkg" (sr_entry "git+https://custom.org/pkg") 198 + in 199 + let dp = dune_proj () in 200 + check_dev_repo "sources.toml entry wins over origin derivation" 201 + (Some ("git+https://custom.org/pkg", "git+https://custom.org/pkg#main")) 202 + (Pkg.derive_dev_repo ~sources ~subtree:"pkg" dp) 203 + 204 + (* {1 derive_dev_repo: real-world scenarios} *) 205 + 206 + let test_derive_memtrace_scenario () = 207 + (* The actual memtrace case: sources.toml has tangled URL, 208 + dune-project has github, branch is master *) 209 + let sources = 210 + SR.add SR.empty ~subtree:"memtrace" 211 + (sr_entry ~branch:(Some "master") 212 + ~upstream:(Some "git+https://github.com/janestreet/memtrace") 213 + "git@git.recoil.org:gazagnaire.org/memtrace") 214 + in 215 + let dp = 216 + dune_proj ~source:(Github { user = "janestreet"; repo = "memtrace" }) () 217 + in 218 + check_dev_repo "memtrace: sources.toml tangled URL with master branch" 219 + (Some 220 + ( "git@git.recoil.org:gazagnaire.org/memtrace", 221 + "git@git.recoil.org:gazagnaire.org/memtrace#master" )) 222 + (Pkg.derive_dev_repo ~sources ~subtree:"memtrace" dp) 223 + 224 + let test_derive_no_entry_uses_dune_project () = 225 + (* Package not in sources.toml, but has dune-project source *) 226 + let sources = 227 + SR.add SR.empty ~subtree:"other" (sr_entry "git+https://example.com/other") 228 + in 229 + let dp = 230 + dune_proj ~source:(Tangled { host = "gazagnaire.org"; repo = "my-pkg" }) () 231 + in 232 + check_dev_repo "unrelated source entry doesn't affect lookup" 233 + (Some 234 + ( "git+https://tangled.org/gazagnaire.org/my-pkg", 235 + "git+https://tangled.org/gazagnaire.org/my-pkg#main" )) 236 + (Pkg.derive_dev_repo ~sources ~subtree:"my-pkg" dp) 237 + 28 238 let suite = 29 239 ( "Pkg", 30 240 [ ··· 32 242 Alcotest.test_case "matches by subtree" `Quick 33 243 test_matches_name_by_subtree; 34 244 Alcotest.test_case "no match" `Quick test_matches_name_no_match; 245 + (* derive_dev_repo: sources.toml override *) 246 + Alcotest.test_case "derive: sources.toml override" `Quick 247 + test_derive_sources_override; 248 + Alcotest.test_case "derive: sources.toml with branch" `Quick 249 + test_derive_sources_override_with_branch; 250 + Alcotest.test_case "derive: sources.toml branch from dune" `Quick 251 + test_derive_sources_override_branch_from_dune; 252 + Alcotest.test_case "derive: sources.toml no branch" `Quick 253 + test_derive_sources_override_no_branch; 254 + (* derive_dev_repo: dune-project fallback *) 255 + Alcotest.test_case "derive: github" `Quick test_derive_from_github; 256 + Alcotest.test_case "derive: gitlab" `Quick test_derive_from_gitlab; 257 + Alcotest.test_case "derive: tangled" `Quick test_derive_from_tangled; 258 + Alcotest.test_case "derive: uri with branch" `Quick test_derive_from_uri; 259 + Alcotest.test_case "derive: uri no branch" `Quick 260 + test_derive_from_uri_no_branch; 261 + (* derive_dev_repo: origin fallback *) 262 + Alcotest.test_case "derive: origin" `Quick test_derive_from_origin; 263 + Alcotest.test_case "derive: origin trailing slash" `Quick 264 + test_derive_from_origin_trailing_slash; 265 + (* derive_dev_repo: no source *) 266 + Alcotest.test_case "derive: none" `Quick test_derive_none; 267 + (* derive_dev_repo: priority *) 268 + Alcotest.test_case "derive: sources wins over dune" `Quick 269 + test_derive_sources_wins_over_dune; 270 + Alcotest.test_case "derive: dune wins over origin" `Quick 271 + test_derive_dune_wins_over_origin; 272 + Alcotest.test_case "derive: sources wins over origin" `Quick 273 + test_derive_sources_wins_over_origin; 274 + (* derive_dev_repo: real-world *) 275 + Alcotest.test_case "derive: memtrace scenario" `Quick 276 + test_derive_memtrace_scenario; 277 + Alcotest.test_case "derive: unrelated entry" `Quick 278 + test_derive_no_entry_uses_dune_project; 35 279 ] )