Skip to content

Commit

Permalink
Make the handling of the avoid-version flag optional
Browse files Browse the repository at this point in the history
  • Loading branch information
kit-ty-kate committed Jan 28, 2022
1 parent d5c95bd commit 3767312
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 24 deletions.
42 changes: 26 additions & 16 deletions lib-cudf/opam_0install_cudf.ml
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
type context = {
universe : Cudf.universe;
constraints : (Cudf_types.pkgname * (Cudf_types.relop * Cudf_types.version)) list;
prefer_oldest : bool;
handle_avoid_version : bool;
fresh_id : int ref;
}

let tagged_with_avoid_version pkg =
List.exists (function
| "avoid-version", `Bool b -> b
| _ -> false
) pkg.Cudf.pkg_extra

let version_rev_compare ~prefer_oldest pkg1 pkg2 =
let rev cmp = if prefer_oldest then cmp else -cmp in
match tagged_with_avoid_version pkg1, tagged_with_avoid_version pkg2 with
| true, true | false, false -> rev (Int.compare pkg1.Cudf.version pkg2.Cudf.version)
| true, false -> 1
| false, true -> -1
let version_rev_compare context pkg1 pkg2 =
let rev_cmp () =
if context.prefer_oldest then
Int.compare pkg1.Cudf.version pkg2.Cudf.version
else
Int.compare pkg2.Cudf.version pkg1.Cudf.version
in
if context.handle_avoid_version then
match tagged_with_avoid_version pkg1, tagged_with_avoid_version pkg2 with
| true, true | false, false -> rev_cmp ()
| true, false -> 1
| false, true -> -1
else
rev_cmp ()

module Context = struct
type rejection = UserConstraint of Cudf_types.vpkg

type t = {
universe : Cudf.universe;
constraints : (Cudf_types.pkgname * (Cudf_types.relop * Cudf_types.version)) list;
prefer_oldest : bool;
fresh_id : int ref;
}
type t = context

let user_restrictions t name =
List.fold_left (fun acc (name', c) ->
Expand All @@ -35,8 +46,7 @@ module Context = struct
| [] ->
[] (* Package not found *)
| versions ->
let prefer_oldest = t.prefer_oldest in
List.fast_sort (version_rev_compare ~prefer_oldest) versions (* Higher versions are preferred. *)
List.fast_sort (version_rev_compare t) versions (* Higher versions are preferred. *)
|> List.map (fun pkg ->
let rec check_constr = function
| [] -> (pkg.Cudf.version, Ok pkg)
Expand Down Expand Up @@ -82,8 +92,8 @@ type t = Context.t
type selections = Solver.Output.t
type diagnostics = Input.requirements (* So we can run another solve *)

let create ?(prefer_oldest=false) ~constraints universe =
{ Context.universe; constraints; prefer_oldest; fresh_id = ref 0 }
let create ?(prefer_oldest=false) ?(handle_avoid_version=false) ~constraints universe =
{ universe; constraints; prefer_oldest; handle_avoid_version; fresh_id = ref 0 }

let solve context pkgs =
let req = requirements ~context pkgs in
Expand Down
11 changes: 9 additions & 2 deletions lib-cudf/opam_0install_cudf.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ type diagnostics

val create :
?prefer_oldest:bool ->
?handle_avoid_version:bool -> (* TODO: Make it true by default on the next major breaking release *)
constraints:(Cudf_types.pkgname * (Cudf_types.relop * Cudf_types.version)) list ->
Cudf.universe ->
t
(** [create ~constraints universe] is a solver that gets candidates from [universe],
filtering them using [constraints].
@param prefer_oldest if [true] the solver is set to return the least
up-to-date version of each package, if a solution exists. This is [false] by
default.
up-to-date version of each package, if a solution exists.
This is [false] by default.
@before 0.4 the [prefer_oldest] parameter did not exist.
@param handle_avoid_verison if [true] the solver is set to handle the
avoid-version flag that opam 2.1 introduced. This makes the solver try
its best to avoid the versions tagged with this flag.
This is [false] by default.
@before 0.4 the [prefer_oldest] parameter did not exist. *)

val solve :
Expand Down
12 changes: 6 additions & 6 deletions test/cudf/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ let universe =
{Cudf.default_package with package = "d"; version = 4; pkg_extra = [("avoid-version", `Bool true)]};
]

let solve ?prefer_oldest req =
let x = Opam_0install_cudf.create ?prefer_oldest ~constraints:[] universe in
let solve ?prefer_oldest ?handle_avoid_version req =
let x = Opam_0install_cudf.create ?prefer_oldest ?handle_avoid_version ~constraints:[] universe in
match Opam_0install_cudf.solve x req with
| Ok sel -> Ok (Opam_0install_cudf.packages_of_result sel)
| Error diag -> Error (Opam_0install_cudf.diagnostics ~verbose:true diag)
Expand All @@ -45,22 +45,22 @@ let simple_avoid_1 () =
let oldest_avoid_1 () =
Alcotest.(check (result (list (pair string int)) string))
"equal" (Ok [("b", 1)])
(solve ~prefer_oldest:true [("b", `Essential)])
(solve ~prefer_oldest:true ~handle_avoid_version:true [("b", `Essential)])

let simple_avoid_2 () =
Alcotest.(check (result (list (pair string int)) string))
"equal" (Ok [("c", 4)])
(solve [("c", `Essential)])
(solve ~handle_avoid_version:true [("c", `Essential)])

let oldest_avoid_2 () =
Alcotest.(check (result (list (pair string int)) string))
"equal" (Ok [("c", 2)])
(solve ~prefer_oldest:true [("c", `Essential)])
(solve ~prefer_oldest:true ~handle_avoid_version:true [("c", `Essential)])

let simple_avoid_3 () =
Alcotest.(check (result (list (pair string int)) string))
"equal" (Ok [("d", 3)])
(solve [("d", `Essential)])
(solve ~handle_avoid_version:true [("d", `Essential)])

let oldest_avoid_3 () =
Alcotest.(check (result (list (pair string int)) string))
Expand Down

0 comments on commit 3767312

Please sign in to comment.