Skip to content

Commit

Permalink
TODO stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
sim642 committed Jul 4, 2024
1 parent 2cb41e4 commit 1844eca
Showing 1 changed file with 103 additions and 11 deletions.
114 changes: 103 additions & 11 deletions src/depgraph/opam_installed_graph.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,113 @@ module Ofml = OpamFormula

module GOper = Graph.Oper.P (G)

let g_of_depends ~st ~env depends =
let {u_installed; u_depends; u_depopts; _} = Opam_state_compat.universe_query st in
let g_of_depends ~st ~env:_ depends =

let partial_env =
let vars = [
"build", true;
"post", true;
(* "dev", dev;
"with-doc", doc;
"with-test", test; *)
(* "with-dev-setup", dev_setup; *)
] |> List.map (fun (v, f) -> v, if f then None else Some (B false))
in
fun var ->
List.find_map (fun (v,c) ->
if String.equal v (OpamVariable.Full.to_string var) then
c else None) vars
in

let rec ors_to_list = function
| Empty -> []
| Or (e,f) ->
List.rev_append (rev_ors_to_list e) (ors_to_list f)
| Block f -> ors_to_list f
| x -> [x]
and rev_ors_to_list = function
| Empty -> []
| Or (e,f) ->
List.rev_append (ors_to_list f) (rev_ors_to_list e)
| Block f -> rev_ors_to_list f
| x -> [x]
in

let is_conjunction t =
let rec aux = function
| Or _ -> false
| And (a,b) -> aux a && aux b
| Block a -> aux a
| _ -> true
in
aux t
in

let formula_to_dnf t =
let disj = rev_ors_to_list t in
let atoms = Ofml.fold_right (fun acc a -> a::acc) [] in
if List.for_all is_conjunction disj then
List.rev_map atoms disj
else
List.rev_map atoms @@ rev_ors_to_list @@ OpamFormula.dnf_of_formula t
in

let fold_all_depends f acc package =
let deps = Opkg.Map.find package u_depends |> OpamPackageVar.filter_depends_formula ~env in
let depopts = Opkg.Map.find package u_depopts |> OpamPackageVar.filter_depends_formula ~env in
(* let opam = Opkg.Map.find package st.OpamStateTypes.opams in *)

let map =
OpamSwitchState.opam st package
|> OpamFile.OPAM.depends
(* remove any irrelevant variables to simplify the output *)
|> OpamFilter.partial_filter_formula partial_env
|> formula_to_dnf
|> List.find_map (fun cnj ->
let is_valid, result =
cnj
(* filter out non-installed dependencies *)
|> List.filter (fun (name, _) ->
OpamSwitchState.is_name_installed st name)
|> List.fold_left_map (fun is_valid orig ->
if not is_valid then
is_valid, orig
else
let filtered =
OpamFilter.filter_deps ~build:true ~post:true ~default:true ~test:true ~doc:true ~dev:true (Atom orig)
in
match filtered with
| Atom (name, _) ->
let package =
OpamSwitchState.find_installed_package_by_name st name
in
let is_valid =
OpamFormula.eval (fun atom ->
OpamFormula.check atom package)
(OpamFormula.to_atom_formula filtered)
in
is_valid, orig
| _ -> false, orig (* should be impossible *)
) true
in
if is_valid then Some result else None
)
|> OpamStd.Option.default []
|> OpamPackage.Name.Map.of_list
in

let fold_depend ~optional acc (name, version_formula) =
(* let deps = Opkg.Map.find package u_depends |> OpamPackageVar.filter_depends_formula ~env in
let depopts = Opkg.Map.find package u_depopts |> OpamPackageVar.filter_depends_formula ~env in *)
(* let deps = OpamFile.OPAM.depends opam in
let depopts = OpamFile.OPAM.depopts opam in *)

let fold_depend ~optional name condition acc =
match OpamSwitchState.find_installed_package_by_name st name with
| package -> f acc package optional version_formula
| package -> f acc package optional condition
| exception Not_found -> acc
in

let acc = Ofml.fold_left (fold_depend ~optional:false) acc deps in
Ofml.fold_left (fold_depend ~optional:true) acc depopts
let acc = Opkg.Name.Map.fold (fold_depend ~optional:false) map acc in
(* Ofml.fold_left (fold_depend ~optional:true) acc depopts *)
acc
in

let fold_all_depexts f acc package =
Expand All @@ -35,8 +127,8 @@ let g_of_depends ~st ~env depends =
let fold_package package g =
let pkg: V.t = OpamPackage package in
let g = G.add_vertex g pkg in
let g = fold_all_depends (fun g depend_package optional version_formula ->
G.add_edge_e g (pkg, OpamFormula {optional; version_formula}, OpamPackage depend_package)
let g = fold_all_depends (fun g depend_package optional condition ->
G.add_edge_e g (pkg, OpamCondition {optional; condition}, OpamPackage depend_package)
) g package
in
fold_all_depexts (fun g depext ->
Expand All @@ -46,7 +138,7 @@ let g_of_depends ~st ~env depends =

match depends with
| None ->
Opkg.Set.fold fold_package u_installed G.empty
Opkg.Set.fold fold_package st.installed G.empty
| Some depends ->
let depends_package = OpamSwitchState.find_installed_package_by_name st (Opkg.Name.of_string depends) in
let rec fold_deps g visited package =
Expand Down

0 comments on commit 1844eca

Please sign in to comment.