Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
dir_context.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123type rejection = | UserConstraint of OpamFormula.atom let ( / ) = Filename.concat let with_dir path fn = let ch = Unix.opendir path in Fun.protect ~finally:(fun () -> Unix.closedir ch) (fun () -> fn ch) let list_dir path = let rec aux acc ch = match Unix.readdir ch with | name -> aux (name :: acc) ch | exception End_of_file -> acc in with_dir path (aux []) type t = { env : string -> OpamVariable.variable_contents option; packages_dir : string; pins : (OpamPackage.Version.t * OpamFile.OPAM.t) OpamPackage.Name.Map.t; constraints : OpamFormula.version_constraint OpamTypes.name_map; (* User-provided constraints *) test : OpamPackage.Name.Set.t; prefer_oldest : bool; } let load t pkg = let { OpamPackage.name; version = _ } = pkg in match OpamPackage.Name.Map.find_opt name t.pins with | Some (_, opam) -> opam | None -> let opam_path = t.packages_dir / OpamPackage.Name.to_string name / OpamPackage.to_string pkg / "opam" in OpamFile.OPAM.read (OpamFile.make (OpamFilename.raw opam_path)) let user_restrictions t name = OpamPackage.Name.Map.find_opt name t.constraints let dev = OpamPackage.Version.of_string "dev" let std_env ?(ocaml_native=true) ?sys_ocaml_version ~arch ~os ~os_distribution ~os_family ~os_version () = function | "arch" -> Some (OpamTypes.S arch) | "os" -> Some (OpamTypes.S os) | "os-distribution" -> Some (OpamTypes.S os_distribution) | "os-version" -> Some (OpamTypes.S os_version) | "os-family" -> Some (OpamTypes.S os_family) | "opam-version" -> Some (OpamVariable.string OpamVersion.(to_string current)) | "sys-ocaml-version" -> sys_ocaml_version |> Option.map (fun v -> OpamTypes.S v) | "ocaml:native" -> Some (OpamTypes.B ocaml_native) | "enable-ocaml-beta-repository" -> None (* Fake variable? *) | v -> OpamConsole.warning "Unknown variable %S" v; None let env t pkg v = if List.mem v OpamPackageVar.predefined_depends_variables then None else match OpamVariable.Full.to_string v with | "version" -> Some (OpamTypes.S (OpamPackage.Version.to_string (OpamPackage.version pkg))) | x -> t.env x let filter_deps t pkg f = let dev = OpamPackage.Version.compare (OpamPackage.version pkg) dev = 0 in let test = OpamPackage.Name.Set.mem (OpamPackage.name pkg) t.test in f |> OpamFilter.partial_filter_formula (env t pkg) |> OpamFilter.filter_deps ~build:true ~post:true ~test ~doc:false ~dev ~default:false let version_compare t v1 v2 = if t.prefer_oldest then OpamPackage.Version.compare v1 v2 else OpamPackage.Version.compare v2 v1 let candidates t name = match OpamPackage.Name.Map.find_opt name t.pins with | Some (version, opam) -> [version, Ok opam] | None -> let versions_dir = t.packages_dir / OpamPackage.Name.to_string name in match list_dir versions_dir with | versions -> let user_constraints = user_restrictions t name in versions |> List.filter_map (fun dir -> match OpamPackage.of_string_opt dir with | Some pkg when Sys.file_exists (versions_dir / dir / "opam") -> Some (OpamPackage.version pkg) | _ -> None ) |> List.sort (version_compare t) |> List.map (fun v -> match user_constraints with | Some test when not (OpamFormula.check_version_formula (OpamFormula.Atom test) v) -> v, Error (UserConstraint (name, Some test)) | _ -> let pkg = OpamPackage.create name v in let opam = load t pkg in let available = OpamFile.OPAM.available opam in match OpamFilter.eval ~default:(B false) (env t pkg) available with | B true -> v, Ok opam | B false -> v, Error Unavailable | _ -> OpamConsole.error "Available expression not a boolean: %s" (OpamFilter.to_string available); v, Error Unavailable ) | exception Unix.Unix_error (Unix.ENOENT, _, _) -> OpamConsole.log "opam-0install" "Package %S not found!" (OpamPackage.Name.to_string name); [] let pp_rejection f = function | UserConstraint x -> Fmt.pf f "Rejected by user-specified constraint %s" (OpamFormula.string_of_atom x) | Unavailable -> Fmt.string f "Availability condition not satisfied" let create ?(prefer_oldest=false) ?(test=OpamPackage.Name.Set.empty) ?(pins=OpamPackage.Name.Map.empty) ~constraints ~env packages_dir = { env; packages_dir; pins; constraints; test; prefer_oldest }