From da630e76940020dac3620cbe7e00fada4e45dd1e Mon Sep 17 00:00:00 2001 From: rand00 Date: Fri, 7 Jan 2022 14:09:34 +0100 Subject: [PATCH] Implemented transitive deps output ('text_transitive' cli arg) --- app/main.ml | 9 +++++++-- src/opam_graph.ml | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/main.ml b/app/main.ml index 23a472a..10af47e 100644 --- a/app/main.ml +++ b/app/main.ml @@ -16,10 +16,15 @@ let () = | [| _ ; output_format; file |] -> ( let switch = read_file file in let data = OpamFile.SwitchExport.read_from_string switch in - let graph = Opam_graph.dependencies data in match output_format with - | "text" -> Format.printf "%a" Opam_graph.pp_graph graph + | "text" -> + let graph = Opam_graph.dependencies data in + Format.printf "%a" Opam_graph.pp_graph graph + | "text_transitive" -> + let graph = Opam_graph.dependencies ~transitive:true data in + Format.printf "%a" Opam_graph.pp_graph graph | "dot" -> + let graph = Opam_graph.dependencies data in let dot = Opam_graph.Dot.of_graph graph in Format.printf "%a" Opam_graph.Dot.pp dot | _ -> failwith "Unsupported output format" diff --git a/src/opam_graph.ml b/src/opam_graph.ml index 5f2f92e..e2bafb4 100644 --- a/src/opam_graph.ml +++ b/src/opam_graph.ml @@ -29,6 +29,33 @@ let direct_dependencies (switch : OpamFile.SwitchExport.t) pkg = let set = filtered_formula_to_pkgs switch (OpamFile.OPAM.depends opam) in filtered_formula_to_pkgs switch ~set (OpamFile.OPAM.depopts opam) +let transitive_dependencies (switch : OpamFile.SwitchExport.t) pkg = + let available = switch.selections.sel_installed in + let rec aux pkg seen_pkgs = + let opam = opam switch pkg in + let set = filtered_formula_to_pkgs switch (OpamFile.OPAM.depends opam) in + let set = filtered_formula_to_pkgs switch ~set (OpamFile.OPAM.depopts opam) in + let transitive_set = + let filtered_set = + set + |> Name_set.filter (fun name -> + OpamPackage.Set.exists + (fun pkg -> pkg.OpamPackage.name = name) + available + && not (Name_set.mem name seen_pkgs) + ) + in + let seen_pkgs = Name_set.union seen_pkgs filtered_set + in + filtered_set + |> Name_set.elements + |> List.concat_map (fun pkg -> aux pkg seen_pkgs |> Name_set.elements) + |> Name_set.of_list + in + Name_set.union set transitive_set + in + aux pkg Name_set.empty + module Name_map = OpamPackage.Name.Map type graph = { @@ -49,7 +76,7 @@ let pp_graph ppf graph = (Name_set.elements deps)))) graph.nodes -let dependencies (switch : OpamFile.SwitchExport.t) = +let dependencies ?(transitive=false) (switch : OpamFile.SwitchExport.t) = let root_pkg = root switch in let top = root_pkg.OpamPackage.name in let graph = { top ; nodes = Name_map.empty } in @@ -58,7 +85,10 @@ let dependencies (switch : OpamFile.SwitchExport.t) = match Name_set.choose_opt work with | None -> graph | Some x -> - let deps = direct_dependencies switch x in + let deps = match transitive with + | true -> transitive_dependencies switch x + | false -> direct_dependencies switch x + in let deps = Name_set.filter (fun name -> OpamPackage.Set.exists