Monorepo management for opam overlays
0
fork

Configure Feed

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

textloc -> loc: rename package, drop Sort_kind, use dune re_export

Rename the shared location/error-infrastructure package to 'loc' (module
Loc), dropping the awkward 'textloc' / 'Textloc' naming. Consumers now
write [Sexpt.Meta], [Sexpt.Error], [Loc.t], etc.

- ocaml-textloc -> ocaml-loc (directory, opam, module).
- Dropped the single-function Sort_kind module; parsers inline the
one-liner at their local Sort.kinded definitions.
- Parser dunes use [(re_export loc)] so downstream consumers don't need
to declare loc in their own dune or opam.
- monopam lint: new [collect_exports] walks META [exports] fields
(dune's re_export metadata) and expands each opam package's
effective dep set with everything its declared deps re-export.
[Fl_split.in_words] replaces the ad-hoc whitespace splitter.
- merlint: drop 'loc' from its dune-project depends -- reaches via
sexpt re_export.
- Consumers (cdm, s3, test files) updated to [Loc.*] naming.

All 360 tests pass (26 loc + 177 xmlt + 60 csvt + 77 sexpt + 20
dune-codec).

+45 -11
+45 -11
lib/lint.ml
··· 46 46 try Ok (Fl_metascanner.parse_lexing (Lexing.from_string content)) 47 47 with Fl_metascanner.Error msg -> Error msg 48 48 49 - (** Collect all [requires] library names from a parsed META, recursively through 50 - sub-packages. *) 51 - let rec collect_requires (pkg : Fl_metascanner.pkg_expr) = 49 + (** Collect values of [field] from a parsed META, recursively through 50 + sub-packages, using findlib's own field splitter [Fl_split.in_words]. *) 51 + let rec collect_field field (pkg : Fl_metascanner.pkg_expr) = 52 52 let own = 53 53 List.concat_map 54 54 (fun (def : Fl_metascanner.pkg_definition) -> 55 - if def.def_var = "requires" then 56 - let v = def.def_value in 57 - let v = String.concat " " (String.split_on_char '\n' v) in 58 - String.split_on_char ' ' v 59 - |> List.filter (fun s -> s <> "" && s <> ",") 60 - else []) 55 + if def.def_var = field then Fl_split.in_words def.def_value else []) 61 56 pkg.pkg_defs 62 57 in 63 58 let children = 64 - List.concat_map (fun (_, child) -> collect_requires child) pkg.pkg_children 59 + List.concat_map 60 + (fun (_, child) -> collect_field field child) 61 + pkg.pkg_children 65 62 in 66 63 own @ children 64 + 65 + let collect_requires = collect_field "requires" 66 + let collect_exports = collect_field "exports" 67 67 68 68 (** Index all library names from a parsed META into [lib_name -> opam_pkg]. *) 69 69 let rec index_meta ~opam_pkg ~prefix (pkg : Fl_metascanner.pkg_expr) index = ··· 352 352 | n -> n) 353 353 issues 354 354 355 + (** Given an opam package name, return the set of opam packages it re-exports 356 + transitively via dune's [(re_export X)]. We read the package's META from 357 + [build_lib] and walk the [exports] field. The empty set is returned if the 358 + META is missing or the package re-exports nothing. *) 359 + let reexports_of_pkg ~fs ~build_lib ~index pkg = 360 + let rec walk seen pkg = 361 + if String_set.mem pkg seen then seen 362 + else 363 + let seen = String_set.add pkg seen in 364 + let meta_path = Fpath.(build_lib / pkg / "META") in 365 + match load_file fs meta_path with 366 + | None -> seen 367 + | Some content -> ( 368 + match parse_meta content with 369 + | Error _ -> seen 370 + | Ok expr -> 371 + let exported = 372 + collect_exports expr 373 + |> List.map (lib_to_package index) 374 + |> List.filter (fun p -> p <> pkg) 375 + in 376 + List.fold_left walk seen exported) 377 + in 378 + String_set.remove pkg (walk String_set.empty pkg) 379 + 355 380 let run ~fs ~monorepo () = 356 381 let index = build_library_index ~fs ~monorepo in 357 382 let build_lib = Fpath.(monorepo / "_build" / "install" / "default" / "lib") in ··· 366 391 else begin 367 392 incr scanned; 368 393 let own_set = String_set.of_list (List.map (fun (n, _, _) -> n) pkgs) in 369 - let all_deps = 394 + let direct_deps = 370 395 List.fold_left 371 396 (fun acc (_, _, all) -> String_set.union acc all) 372 397 String_set.empty pkgs 398 + in 399 + (* Expand declared deps with whatever they re-export, so consumers 400 + don't need to list transitive re-exports explicitly. *) 401 + let all_deps = 402 + String_set.fold 403 + (fun pkg acc -> 404 + String_set.union acc 405 + (reexports_of_pkg ~fs ~build_lib ~index pkg)) 406 + direct_deps direct_deps 373 407 in 374 408 let dune_pkgs = dune_needed_packages ~fs ~index subtree_path in 375 409 List.iter