From 8b8a7532cee44f74f4091e74df5feb1ba6b8142b Mon Sep 17 00:00:00 2001 From: Jon Ludlam Date: Thu, 13 Feb 2025 15:01:50 +0000 Subject: [PATCH] Driver: Check for missing/unknown opam packages Closes #1302, closes #1296 --- src/driver/bin/odoc_driver.ml | 14 ++++++++++++++ src/driver/opam.ml | 23 +++++++++++++++++++++++ src/driver/opam.mli | 1 + 3 files changed, 38 insertions(+) diff --git a/src/driver/bin/odoc_driver.ml b/src/driver/bin/odoc_driver.ml index 53735a0c46..210485aa6e 100644 --- a/src/driver/bin/odoc_driver.ml +++ b/src/driver/bin/odoc_driver.ml @@ -1,6 +1,19 @@ (* Odoc driver *) open Odoc_driver_lib +let check_packages packages = + match packages with + | [] -> () + | _ -> ( + match Opam.check packages with + | Ok () -> () + | Error missing -> + Logs.err (fun m -> + m "Error: Unknown/uninstalled packages: %a" + Fmt.Dump.(list string) + (Util.StringSet.elements missing)); + exit 1) + let run_inner ~odoc_dir ~odocl_dir ~index_dir ~mld_dir ~compile_grep ~link_grep ~generate_grep ~index_grep ~remap ~index_mld packages { @@ -20,6 +33,7 @@ let run_inner ~odoc_dir ~odocl_dir ~index_dir ~mld_dir ~compile_grep ~link_grep if verbose then Logs.set_level (Some Logs.Debug); Logs.set_reporter (Logs_fmt.reporter ()); + check_packages packages; Stats.init_nprocs nb_workers; let index_mld_content = diff --git a/src/driver/opam.ml b/src/driver/opam.ml index d9a85f77aa..8fc1ee1cc2 100644 --- a/src/driver/opam.ml +++ b/src/driver/opam.ml @@ -281,6 +281,29 @@ let dune_overrides () = []) | _ -> []) +let check pkgs = + let cmd = + Cmd.( + opam % "list" % "-i" % "--columns" % "package" % "--color" % "never" + % "-s") + in + let cmd = List.fold_left (fun cmd pkg -> Cmd.(cmd % pkg)) cmd pkgs in + let out = Util.lines_of_process cmd in + let res = + List.filter_map + (fun x -> + match Astring.String.cut ~sep:"." x with + | Some (name, _version) -> Some name + | None -> None) + out + in + let missing = Util.StringSet.(diff (of_list pkgs) (of_list res)) in + let dune_pkgnames = + Util.StringSet.of_list (List.map (fun (p, _) -> p.name) (dune_overrides ())) + in + let missing = Util.StringSet.(diff missing dune_pkgnames) in + if Util.StringSet.cardinal missing = 0 then Ok () else Error missing + let pkg_to_dir_map () = let dune_overrides = dune_overrides () in let pkgs = all_opam_packages () in diff --git a/src/driver/opam.mli b/src/driver/opam.mli index ce86e45320..76a7d2c8cc 100644 --- a/src/driver/opam.mli +++ b/src/driver/opam.mli @@ -20,6 +20,7 @@ val all_opam_packages : unit -> package list val classify_docs : Fpath.t -> string option -> Fpath.t list -> doc_file list +val check : string list -> (unit, Util.StringSet.t) Result.t val deps : string list -> package list val pkg_to_dir_map : unit -> fpaths_of_package * package_of_fpath val pp : Format.formatter -> package -> unit