Skip to content

Commit

Permalink
Use any kind of formula for compiler constraints
Browse files Browse the repository at this point in the history
So now, one can write:

    ocaml-version: [ >= 3.12.1 & <= 4.00.0 ]
  • Loading branch information
samoht committed Oct 8, 2012
1 parent 0b1f20e commit 247d8aa
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 66 deletions.
2 changes: 1 addition & 1 deletion opam.ocp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ begin library "opam-lib"
"opamParallel.ml" "opamParallel.ml"
"opamFilename.ml" "opamFilename.ml"
"opamPackage.ml" "opamPackage.ml"
"opamFormula.ml"
"opamVersion.ml" "opamVersion.ml"
"opamVariable.ml" "opamVariable.ml"
"opamAlias.ml" "opamAlias.ml"
"opamFormula.ml"
"opamTypes.ml" "opamTypes.ml"
"opamFormat.ml" "opamFormat.ml"
"opamParser.mly" "opamParser.mly"
Expand Down
45 changes: 3 additions & 42 deletions src/opamClient.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ let available_packages root compiler config pinned packages =
let filter nv = let filter nv =
let opam = OpamFile.OPAM.read (OpamPath.opam root nv) in let opam = OpamFile.OPAM.read (OpamPath.opam root nv) in
let consistent_ocaml_version = let consistent_ocaml_version =
let atom (r,v) = OpamVersion.Compiler.compare ocaml_version r v in
match OpamFile.OPAM.ocaml_version opam with match OpamFile.OPAM.ocaml_version opam with
| None -> true | None -> true
| Some (r,v) -> OpamVersion.Compiler.compare ocaml_version r v in | Some c -> OpamFormula.eval atom c in
let consistent_pinned_version = let consistent_pinned_version =
not (OpamPackage.Name.Map.mem (OpamPackage.name nv) pinned) || not (OpamPackage.Name.Map.mem (OpamPackage.name nv) pinned) ||
match OpamPackage.Name.Map.find (OpamPackage.name nv) pinned with match OpamPackage.Name.Map.find (OpamPackage.name nv) pinned with
Expand Down Expand Up @@ -259,46 +260,6 @@ let find_installed_package_by_name t name =
with Not_found -> with Not_found ->
OpamGlobals.error_and_exit "Package %s is not installed" (OpamPackage.Name.to_string name) OpamGlobals.error_and_exit "Package %s is not installed" (OpamPackage.Name.to_string name)


(* Remove the packages which does not fullfil the compiler constraints
& deal with pinned packages. *)
let packages t =
let ocaml_version =
let current_alias = t.alias in
let default_alias = OpamAlias.of_string OpamGlobals.default_alias in
if current_alias = default_alias then (
let current = OpamVersion.Compiler.current () in
let system = OpamFile.Config.system_version t.config in
match current, system with
| None , None -> OpamGlobals.error_and_exit "No OCaml compiler installed."
| None , Some s -> s
| Some c, Some s ->
if s <> c then (
OpamGlobals.warning "The version of OCaml in your path (%S) \
is not the same as the one OPAM has been \
initialized with (%S)."
(OpamVersion.Compiler.to_string c)
(OpamVersion.Compiler.to_string s)
);
s
| Some c, None -> c
) else
match t.compiler with
| Some v -> v
| None -> OpamGlobals.error_and_exit "No OCaml compiler defined."in
let filter nv =
let opam = opam t nv in
let consistent_ocaml_version =
match OpamFile.OPAM.ocaml_version opam with
| None -> true
| Some (r,v) -> OpamVersion.Compiler.compare ocaml_version r v in
let consistent_pinned_version =
not (OpamPackage.Name.Map.mem (OpamPackage.name nv) t.pinned) ||
match OpamPackage.Name.Map.find (OpamPackage.name nv) t.pinned with
| Version v -> v = OpamPackage.version nv
| _ -> true (* any version is fine, as this will be overloaded on install *) in
consistent_ocaml_version && consistent_pinned_version in
OpamPackage.Set.filter filter t.packages

let find_package_by_name t name = let find_package_by_name t name =
let r = OpamPackage.Set.filter (fun nv -> OpamPackage.name nv = name) t.packages in let r = OpamPackage.Set.filter (fun nv -> OpamPackage.name nv = name) t.packages in
if OpamPackage.Set.is_empty r then if OpamPackage.Set.is_empty r then
Expand Down
4 changes: 2 additions & 2 deletions src/opamFile.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ module OPAM = struct
] @ ( ] @ (
match t.ocaml_version with match t.ocaml_version with
| None -> [] | None -> []
| Some v -> [ Variable (s_ocaml_version, OpamFormat.make_constraint v) ] | Some v -> [ Variable (s_ocaml_version, OpamFormat.make_compiler_constraint v) ]
) @ ) @
List.map (fun (s, v) -> Variable (s, v)) t.others; List.map (fun (s, v) -> Variable (s, v)) t.others;
} in } in
Expand Down Expand Up @@ -735,7 +735,7 @@ module OPAM = struct
let conflicts = OpamFormat.assoc_default OpamFormula.Empty s s_conflicts OpamFormat.parse_formula in let conflicts = OpamFormat.assoc_default OpamFormula.Empty s s_conflicts OpamFormat.parse_formula in
let libraries = OpamFormat.assoc_list s s_libraries (OpamFormat.parse_list (OpamFormat.parse_string |> OpamVariable.Section.of_string)) in let libraries = OpamFormat.assoc_list s s_libraries (OpamFormat.parse_list (OpamFormat.parse_string |> OpamVariable.Section.of_string)) in
let syntax = OpamFormat.assoc_list s s_syntax (OpamFormat.parse_list (OpamFormat.parse_string |> OpamVariable.Section.of_string)) in let syntax = OpamFormat.assoc_list s s_syntax (OpamFormat.parse_list (OpamFormat.parse_string |> OpamVariable.Section.of_string)) in
let ocaml_version = OpamFormat.assoc_option s s_ocaml_version OpamFormat.parse_constraint in let ocaml_version = OpamFormat.assoc_option s s_ocaml_version OpamFormat.parse_compiler_constraint in
let parse_file = OpamFormat.parse_option (OpamFormat.parse_string |> OpamFilename.Base.of_string) OpamFormat.parse_filter in let parse_file = OpamFormat.parse_option (OpamFormat.parse_string |> OpamFilename.Base.of_string) OpamFormat.parse_filter in
let patches = OpamFormat.assoc_list s s_patches (OpamFormat.parse_list parse_file) in let patches = OpamFormat.assoc_list s s_patches (OpamFormat.parse_list parse_file) in
let files = OpamFormat.assoc_list s s_files (OpamFormat.parse_list parse_file) in let files = OpamFormat.assoc_list s s_files (OpamFormat.parse_list parse_file) in
Expand Down
42 changes: 27 additions & 15 deletions src/opamFormat.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -349,16 +349,6 @@ let parse_relop = function
| "<" -> `Lt | "<" -> `Lt
| _ -> invalid_arg "parse_relop" | _ -> invalid_arg "parse_relop"
let parse_constraint = function
| List [ Symbol r; String v ] ->
(try (parse_relop r, OpamVersion.Compiler.of_string v)
with _ -> bad_format "Expecting a relop, got %s" r)
| x -> bad_format "Expecting a constraint, got %s" (kind x)
let make_constraint = function
| (name,_), None -> String name
| (name,_), Some (r,v) -> Option (String name, [Symbol r; String v])
let string_of_relop = function let string_of_relop = function
| `Eq -> "=" | `Eq -> "="
| `Geq -> ">=" | `Geq -> ">="
Expand All @@ -367,11 +357,33 @@ let string_of_relop = function
| `Lt -> "<" | `Lt -> "<"
| _ -> invalid_arg "parse_relop" | _ -> invalid_arg "parse_relop"
let make_constraint (r, v) = let rec parse_compiler_constraint t =
List [ let module F = OpamFormula in
Symbol (string_of_relop r); match t with
String (OpamVersion.Compiler.to_string v); | [] -> F.Empty
] | [Symbol r; String v ] ->
(try F.Atom (parse_relop r, OpamVersion.Compiler.of_string v)
with _ -> bad_format "Expecting a relop, got %s" r)
| [Group g] -> parse_compiler_constraint g
| e1::e2 :: Symbol "|" :: e3 -> F.Or (parse_compiler_constraint [e1;e2], parse_compiler_constraint e3)
| e1::e2 :: Symbol "&" :: e3 -> F.And (parse_compiler_constraint [e1;e2], parse_compiler_constraint e3)
| x -> bad_format "Expecting a compiler constraint, got %s" (kinds x)
let parse_compiler_constraint = function
| List l -> parse_compiler_constraint l
| x -> bad_format "Expecting a list, got %s" (kind x)
let rec make_compiler_constraint t =
let module F = OpamFormula in
match t with
| F.Empty -> []
| F.Atom (r, v) -> [Symbol (string_of_relop r); String (OpamVersion.Compiler.to_string v)]
| F.Block f -> [Group (make_compiler_constraint f)]
| F.And(e,f) -> make_compiler_constraint e @ [Symbol "|"] @ make_compiler_constraint f
| F.Or(e,f) -> make_compiler_constraint e @ [Symbol "|"] @ make_compiler_constraint f
let make_compiler_constraint t =
List (make_compiler_constraint t)
let parse_env_variable v = let parse_env_variable v =
let l = parse_sequence [ let l = parse_sequence [
Expand Down
8 changes: 4 additions & 4 deletions src/opamFormat.mli
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ val parse_opt_formula : value -> formula
(** Build a formula where OR are implicit. *) (** Build a formula where OR are implicit. *)
val make_opt_formula : formula -> value val make_opt_formula : formula -> value


(** Parse a simple constraint *) (** Parse compiler constraints *)
val parse_constraint: value -> compiler_constraint val parse_compiler_constraint: value -> compiler_constraint


(** Build a simple constraint *) (** Build a compiler constraint *)
val make_constraint: compiler_constraint -> value val make_compiler_constraint: compiler_constraint -> value


(** {2 Environment variables} *) (** {2 Environment variables} *)


Expand Down
7 changes: 7 additions & 0 deletions src/opamFormula.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ let rec fold_left f i = function


type t = (OpamPackage.Name.t * (string * OpamPackage.Version.t) formula) formula type t = (OpamPackage.Name.t * (string * OpamPackage.Version.t) formula) formula


let rec eval atom = function
| Empty -> true
| Atom x -> atom x
| Block x -> eval atom x
| And(x,y) -> eval atom x && eval atom y
| Or(x,y) -> eval atom x && eval atom y

let to_string t = let to_string t =
let string_of_constraint (relop, version) = let string_of_constraint (relop, version) =
Printf.sprintf "%s %s" relop (OpamPackage.Version.to_string version) in Printf.sprintf "%s %s" relop (OpamPackage.Version.to_string version) in
Expand Down
3 changes: 3 additions & 0 deletions src/opamFormula.mli
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type 'a formula =
| And of 'a formula * 'a formula | And of 'a formula * 'a formula
| Or of 'a formula * 'a formula | Or of 'a formula * 'a formula


(** Eval a formula *)
val eval: ('a -> bool) -> 'a formula -> bool

(** Pretty print a formula *) (** Pretty print a formula *)
val string_of_formula: ('a -> string) -> 'a formula -> string val string_of_formula: ('a -> string) -> 'a formula -> string


Expand Down
2 changes: 1 addition & 1 deletion src/opamVersion.ml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Compiler = struct


include OpamMisc.Base include OpamMisc.Base


type constr = relop * t type constr = (relop * t) OpamFormula.formula


let current () = let current () =
match OpamSystem.ocaml_version () with match OpamSystem.ocaml_version () with
Expand Down
2 changes: 1 addition & 1 deletion src/opamVersion.mli
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module Compiler: sig
include OpamMisc.ABSTRACT include OpamMisc.ABSTRACT


(** Compiler constraint *) (** Compiler constraint *)
type constr = relop * t type constr = (relop * t) OpamFormula.formula


(** Return the version of the compiler currently installed *) (** Return the version of the compiler currently installed *)
val current: unit -> t option val current: unit -> t option
Expand Down

0 comments on commit 247d8aa

Please sign in to comment.