Odoc docs
0

Configure Feed

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

odd / lib / deps.ml
1.9 kB 59 lines
1module SS = Set.Make (String) 2 3let mentions_post (cond : OpamTypes.condition) = 4 OpamFormula.fold_left 5 (fun acc (fc : OpamTypes.filter OpamTypes.filter_or_constraint) -> 6 acc 7 || 8 match fc with 9 | Filter f -> 10 List.exists 11 (fun v -> OpamVariable.Full.to_string v = "post") 12 (OpamFilter.variables f) 13 | Constraint _ -> false) 14 false cond 15 16let names_of_formula (ff : OpamTypes.filtered_formula) = 17 OpamFormula.fold_left 18 (fun acc (name, cond) -> 19 if mentions_post cond then acc 20 else SS.add (OpamPackage.Name.to_string name) acc) 21 SS.empty ff 22 23let direct_deps sw ~name ~version = 24 let path = Fpath.(Switch.packages_dir sw / (name ^ "." ^ version) / "opam") in 25 match 26 OpamFile.OPAM.read (OpamFile.make (OpamFilename.raw (Fpath.to_string path))) 27 with 28 | exception _ -> SS.empty 29 | opam -> 30 SS.union 31 (names_of_formula (OpamFile.OPAM.depends opam)) 32 (names_of_formula (OpamFile.OPAM.depopts opam)) 33 34let order ?(warn = fun _ -> ()) sw names = 35 let installed = Switch.installed sw in 36 let version_of n = 37 List.find_map 38 (fun (n', v) -> if String.equal n n' then Some v else None) 39 installed 40 in 41 let targets = SS.filter (fun n -> version_of n <> None) (SS.of_list names) in 42 let state = Hashtbl.create 16 in 43 let out = ref [] in 44 let rec visit n = 45 match Hashtbl.find_opt state n with 46 | Some `Done -> () 47 | Some `Visiting -> 48 warn (Printf.sprintf "dependency cycle through %s; breaking it" n) 49 | None -> 50 Hashtbl.replace state n `Visiting; 51 let version = Option.get (version_of n) in 52 SS.iter visit (SS.inter (direct_deps sw ~name:n ~version) targets); 53 Hashtbl.replace state n `Done; 54 out := n :: !out 55 in 56 (* SS.iter is in increasing element order, so the result is 57 deterministic. *) 58 SS.iter visit targets; 59 List.rev !out