Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check OCaml version of lockfile against the switch version #268

Merged
merged 4 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
`opam-monorepo`. To control this a new optional Opam file field,
`x-opam-monorepo-opam-provided` is introduced. Its value is a list of package
names that are to be excluded from being pulled (#234, @Leonidas-from-XIV)
- Show an error message when the OCaml version of the lock file does not match
the OCaml version of the switch (#267, #268, @Leonidas-from-XIV)

### Changed

Expand Down
34 changes: 31 additions & 3 deletions cli/pull.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,37 @@ let run (`Yes yes) (`Root root) (`Lockfile explicit_lockfile)
Common.filter_duniverse ~to_consider:duniverse_repos duniverse
in
let* () = check_dune_lang_version ~yes ~root in
OpamGlobalState.with_ `Lock_none (fun global_state ->
Pull.duniverse ~global_state ~root ~full
~trim_clone:(not keep_git_dir) duniverse)
OpamGlobalState.with_ `Lock_none @@ fun global_state ->
let* locked_ocaml_version =
Lockfile.ocaml_version lockfile
|> Result.of_option ~error:(`Msg "OCaml compiler not in lockfile")
in
OpamSwitchState.with_ `Lock_none global_state @@ fun switch_state ->
let switch_ocaml_version =
OpamSwitchState.get_package switch_state Config.compiler_package_name
|> OpamPackage.version
in
let* pulled =
Pull.duniverse ~global_state ~root ~full ~trim_clone:(not keep_git_dir)
duniverse
in
(match
Opam.version_is_at_least locked_ocaml_version switch_ocaml_version
with
| true -> ()
| false ->
Logs.warn (fun l ->
Leonidas-from-XIV marked this conversation as resolved.
Show resolved Hide resolved
l
"Pulling duniverse succeeded but the version of the OCaml \
compiler does not match the lockfile: %a in lockfile, yet %a \
in switch.\n\
You might want to change the compiler version of your switch \
accordingly:\n\
opam install %a.%a --update-invariant" Opam.Pp.version
locked_ocaml_version Opam.Pp.version switch_ocaml_version
Opam.Pp.package_name Config.compiler_package_name
Opam.Pp.version locked_ocaml_version));
Ok pulled

let info =
let open Cmdliner in
Expand Down
2 changes: 2 additions & 0 deletions lib/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ let base_packages =
|> List.map ~f:OpamPackage.Name.of_string
|> OpamPackage.Name.Set.of_list

let compiler_package_name = OpamPackage.Name.of_string "ocaml-base-compiler"

let duniverse_opam_repo =
"git+https://github.com/dune-universe/opam-overlays.git"

Expand Down
7 changes: 7 additions & 0 deletions lib/lockfile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,13 @@ let create ~source_config ~root_packages ~dependency_entries ~root_depexts
source_config;
}

let ocaml_version { depends; _ } =
List.find_map depends ~f:(fun { Depends.package; vendored = _ } ->
let name = OpamPackage.name package in
match OpamPackage.Name.equal name Config.compiler_package_name with
| true -> Some (OpamPackage.version package)
| false -> None)

let url_to_duniverse_url url =
let url_res = Duniverse.Repo.Url.from_opam_url url in
Result.map_error url_res ~f:(function `Msg msg ->
Expand Down
2 changes: 2 additions & 0 deletions lib/lockfile.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ val create :

val to_duniverse : t -> (Duniverse.t, [ `Msg of string ]) result

val ocaml_version : t -> OpamPackage.Version.t option

val save :
opam_monorepo_cwd:Fpath.t ->
file:Fpath.t ->
Expand Down
5 changes: 5 additions & 0 deletions lib/opam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ let depends_on_dune ~allow_jbuilder (formula : OpamTypes.filtered_formula) =
in
depends_on_any packages formula

let version_is_at_least locked_version =
let version_constraint = (`Geq, locked_version) in
let version_formula = OpamFormula.Atom version_constraint in
OpamFormula.check_version_formula version_formula

let pull_tree ~url ~hashes ~dir global_state =
let dir_str = Fpath.to_string dir in
let cache_dir =
Expand Down
4 changes: 4 additions & 0 deletions lib/opam.mli
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ val depends_on_compiler_variants : OpamTypes.filtered_formula -> bool
This is detected by looking direct dependencies on ocaml-variants or dependencies on
any relevant ocaml-option-* packages. *)

val version_is_at_least : OpamPackage.Version.t -> OpamPackage.Version.t -> bool
(** [version_is_at_least minimum to_check] returns [true] if the version
[to_check] is greater or equal to [minimum]. *)

val pull_tree :
url:OpamUrl.t ->
hashes:OpamHash.t list ->
Expand Down
4 changes: 4 additions & 0 deletions stdext/result.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ let bind ~f r = bind r f

let map ~f = map f

(* some useful functions inspired by Jane Street Base *)

let of_option v ~error = match v with Some v -> Ok v | None -> Error error

module O = struct
let ( >>= ) res f = bind ~f res

Expand Down
2 changes: 2 additions & 0 deletions stdext/result.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ val bind : f:('a -> ('b, 'err) t) -> ('a, 'err) t -> ('b, 'err) t

val map : f:('a -> 'b) -> ('a, 'err) t -> ('b, 'err) t

val of_option : 'ok option -> error:'err -> ('ok, 'err) t

module O : sig
val ( >>= ) : ('a, 'err) t -> ('a -> ('b, 'err) t) -> ('b, 'err) t

Expand Down