Skip to content

Commit

Permalink
[API] Make ?lock_kind always non-optional to avoid breaking the libra…
Browse files Browse the repository at this point in the history
…ry users after they upgrade their opam root
  • Loading branch information
kit-ty-kate committed Feb 11, 2025
1 parent 4aa865a commit ca23d8e
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 55 deletions.
4 changes: 3 additions & 1 deletion src/client/opamListCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,9 @@ let apply_selector ~base st = function
in
let selections =
if switch = st.switch then OpamSwitchState.selections st
else OpamSwitchState.load_selections st.switch_global switch
else
OpamSwitchState.load_selections ~lock_kind:`Lock_none
st.switch_global switch
in
List.fold_left (fun acc f ->
let name =
Expand Down
5 changes: 4 additions & 1 deletion src/client/opamSwitchCommand.ml
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,10 @@ let import_t ?ask ?(deps_only=false) importfile t =
opam)
pinned;
(* Save new pinnings *)
let sel = OpamSwitchState.load_selections t.switch_global t.switch in
let sel =
OpamSwitchState.load_selections ~lock_kind:`Lock_write
t.switch_global t.switch
in
S.write
(OpamPath.Switch.selections t.switch_global.root t.switch)
{ sel with sel_pinned = pinned }
Expand Down
2 changes: 1 addition & 1 deletion src/state/opamGlobalState.ml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ let drop gt =
let _ = unlock gt in ()

let with_write_lock ?dontblock gt f =
if OpamStateConfig.is_newer_than_self gt then
if OpamStateConfig.is_newer_than_self ~lock_kind:`Lock_write gt then
OpamConsole.error_and_exit `Locked
"The opam root has been upgraded by a newer version of opam-state \
and cannot be written to";
Expand Down
5 changes: 3 additions & 2 deletions src/state/opamRepositoryState.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ let load lock_kind gt =
log "LOAD-REPOSITORY-STATE %@ %a" (slog OpamFilename.Dir.to_string) gt.root;
let lock = OpamFilename.flock lock_kind (OpamPath.repos_lock gt.root) in
let repos_map = OpamStateConfig.Repos.safe_read ~lock_kind gt in
if OpamStateConfig.is_newer_than_self gt then
if OpamStateConfig.is_newer_than_self ~lock_kind:`Lock_write gt then
log "root version (%s) is greater than running binary's (%s); \
load with best-effort (read-only)"
(OpamVersion.to_string (OpamFile.Config.opam_root_version gt.config))
Expand Down Expand Up @@ -260,7 +260,8 @@ let drop ?cleanup rt =
let _ = unlock ?cleanup rt in ()

let with_write_lock ?dontblock rt f =
if OpamStateConfig.is_newer_than_self rt.repos_global then
if OpamStateConfig.is_newer_than_self ~lock_kind:`Lock_write rt.repos_global
then
OpamConsole.error_and_exit `Locked
"The opam root has been upgraded by a newer version of opam-state \
and cannot be written to";
Expand Down
66 changes: 33 additions & 33 deletions src/state/opamStateConfig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,21 @@ let is_newer config =
(** none -> shouldn't load (write attempt in readonly)
Some true -> everything is fine normal read
Some false -> readonly accorded, load with best effort *)
let is_readonly_opamroot_raw ?(lock_kind=`Lock_write) version =
let is_readonly_opamroot_raw ~lock_kind version =
let newer = is_newer_raw version in
let write = lock_kind = `Lock_write in
if newer && write then None else
Some (newer && not write)

let is_readonly_opamroot_t ?lock_kind gt =
is_readonly_opamroot_raw ?lock_kind
let is_readonly_opamroot_t ~lock_kind gt =
is_readonly_opamroot_raw ~lock_kind
(Some (OpamFile.Config.opam_root_version gt.config))

let is_newer_than_self ?lock_kind gt =
is_readonly_opamroot_t ?lock_kind gt <> Some false
let is_newer_than_self ~lock_kind gt =
is_readonly_opamroot_t ~lock_kind gt <> Some false

let load_if_possible_raw ?lock_kind root version (read,read_wo_err) f =
match is_readonly_opamroot_raw ?lock_kind version with
let load_if_possible_raw ~lock_kind root version (read,read_wo_err) f =
match is_readonly_opamroot_raw ~lock_kind version with
| None ->
OpamConsole.error_and_exit `Locked
"Refusing write access to %s, which is more recent than this version of \
Expand All @@ -271,16 +271,16 @@ let load_if_possible_raw ?lock_kind root version (read,read_wo_err) f =
| Some true -> read_wo_err f
| Some false -> read f

let load_if_possible_t ?lock_kind opamroot config readf f =
load_if_possible_raw ?lock_kind
let load_if_possible_t ~lock_kind opamroot config readf f =
load_if_possible_raw ~lock_kind
opamroot (Some (OpamFile.Config.opam_root_version config)) readf f

let load_if_possible ?lock_kind gt =
load_if_possible_t ?lock_kind gt.root gt.config
let load_if_possible ~lock_kind gt =
load_if_possible_t ~lock_kind gt.root gt.config

let load_config_root ?lock_kind readf opamroot =
let load_config_root ~lock_kind readf opamroot =
let f = OpamPath.config opamroot in
load_if_possible_raw ?lock_kind
load_if_possible_raw ~lock_kind
opamroot
(OpamFile.Config.raw_root_version f)
readf f
Expand All @@ -289,51 +289,51 @@ let safe read read' default =
let safe r f = OpamStd.Option.default default @@ r f in
safe read, safe read'

let safe_load ?lock_kind opamroot =
load_config_root ?lock_kind
let safe_load ~lock_kind opamroot =
load_config_root ~lock_kind
OpamFile.Config.(safe read_opt BestEffort.read_opt empty) opamroot

let load ?lock_kind opamroot =
load_config_root ?lock_kind
let load ~lock_kind opamroot =
load_config_root ~lock_kind
OpamFile.Config.(read_opt, BestEffort.read_opt) opamroot

(* switches *)
module Switch = struct

let load_raw ?lock_kind root config readf switch =
load_if_possible_t ?lock_kind root config readf
let load_raw ~lock_kind root config readf switch =
load_if_possible_t ~lock_kind root config readf
(OpamPath.Switch.switch_config root switch)

let safe_load_t ?lock_kind root switch =
let safe_load_t ~lock_kind root switch =
let config = safe_load ~lock_kind:`Lock_read root in
load_raw ?lock_kind root config
load_raw ~lock_kind root config
OpamFile.Switch_config.(safe read_opt BestEffort.read_opt empty)
switch

let load ?lock_kind gt readf switch =
load_raw ?lock_kind gt.root gt.config readf switch
let load ~lock_kind gt readf switch =
load_raw ~lock_kind gt.root gt.config readf switch

let safe_load ?lock_kind gt switch =
load ?lock_kind gt
let safe_load ~lock_kind gt switch =
load ~lock_kind gt
OpamFile.Switch_config.(safe read_opt BestEffort.read_opt empty)
switch

let read_opt ?lock_kind gt switch =
load ?lock_kind gt
let read_opt ~lock_kind gt switch =
load ~lock_kind gt
OpamFile.Switch_config.(read_opt, BestEffort.read_opt)
switch

let safe_read_selections ?lock_kind gt switch =
load_if_possible ?lock_kind gt
let safe_read_selections ~lock_kind gt switch =
load_if_possible ~lock_kind gt
OpamFile.SwitchSelections.(safe read_opt BestEffort.read_opt empty)
(OpamPath.Switch.selections gt.root switch)

end

(* repos *)
module Repos = struct
let safe_read ?lock_kind gt =
load_if_possible ?lock_kind gt
let safe_read ~lock_kind gt =
load_if_possible ~lock_kind gt
OpamFile.Repos_config.(safe read_opt BestEffort.read_opt empty)
(OpamPath.repos_config gt.root)
end
Expand Down Expand Up @@ -396,13 +396,13 @@ let get_current_switch_from_cwd root =
with OpamPp.Bad_version _ -> None

(* do we want `load_defaults` to fail / run a format upgrade ? *)
let load_defaults ?lock_kind root_dir =
let load_defaults ~lock_kind root_dir =
let current_switch =
match E.switch () with
| Some "" | None -> get_current_switch_from_cwd root_dir
| _ -> (* OPAMSWITCH is set, no need to lookup *) None
in
match try load ?lock_kind root_dir with OpamPp.Bad_version _ -> None with
match try load ~lock_kind root_dir with OpamPp.Bad_version _ -> None with
| None ->
update ?current_switch ();
None
Expand Down
20 changes: 10 additions & 10 deletions src/state/opamStateConfig.mli
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ val opamroot_with_provenance: ?root_dir:dirname -> unit -> provenance * dirname
val opamroot: ?root_dir:dirname -> unit -> dirname

(** Loads the global configuration file, protecting against concurrent writes *)
val load: ?lock_kind: 'a lock -> dirname -> OpamFile.Config.t option
val safe_load: ?lock_kind: 'a lock -> dirname -> OpamFile.Config.t
val load: lock_kind: 'a lock -> dirname -> OpamFile.Config.t option
val safe_load: lock_kind: 'a lock -> dirname -> OpamFile.Config.t

(** Loads the config file from the OPAM root and updates default values for all
related OpamXxxConfig modules. Doesn't read the env yet, the {!init}
Expand All @@ -102,7 +102,7 @@ val safe_load: ?lock_kind: 'a lock -> dirname -> OpamFile.Config.t
Returns the config file that was found, if any *)
val load_defaults:
?lock_kind:'a lock -> OpamFilename.Dir.t -> OpamFile.Config.t option
lock_kind:'a lock -> OpamFilename.Dir.t -> OpamFile.Config.t option

(** Returns the current switch, failing with an error message is none is set. *)
val get_switch: unit -> switch
Expand All @@ -124,31 +124,31 @@ val resolve_local_switch: OpamFilename.Dir.t -> switch -> switch

(** Given the required lock, returns [true] if the opam root is newer than the
binary, so that it can only be loaded read-only by the current binary. *)
val is_newer_than_self: ?lock_kind:'a lock -> 'b global_state -> bool
val is_newer_than_self: lock_kind:'a lock -> 'b global_state -> bool

(** Check config root version regarding self-defined one *)
val is_newer: OpamFile.Config.t -> bool

val load_config_root:
?lock_kind:'a lock ->
lock_kind:'a lock ->
((OpamFile.Config.t OpamFile.t -> 'b) * (OpamFile.Config.t OpamFile.t -> 'b)) ->
dirname -> 'b

module Switch : sig
val safe_load_t:
?lock_kind: 'a lock -> dirname -> switch -> OpamFile.Switch_config.t
lock_kind: 'a lock -> dirname -> switch -> OpamFile.Switch_config.t
val safe_load:
?lock_kind: 'a lock -> 'b global_state -> switch -> OpamFile.Switch_config.t
lock_kind: 'a lock -> 'b global_state -> switch -> OpamFile.Switch_config.t
val safe_read_selections:
?lock_kind: 'a lock -> 'b global_state -> switch -> switch_selections
lock_kind: 'a lock -> 'b global_state -> switch -> switch_selections
val read_opt:
?lock_kind: 'a lock -> 'b global_state -> switch ->
lock_kind: 'a lock -> 'b global_state -> switch ->
OpamFile.Switch_config.t option
end

module Repos : sig
val safe_read:
?lock_kind: 'a lock -> 'b global_state -> OpamFile.Repos_config.t
lock_kind: 'a lock -> 'b global_state -> OpamFile.Repos_config.t
end

(* Raw read an switch config to downgrade its [opam-version] from 2.1 to 2.0.
Expand Down
13 changes: 7 additions & 6 deletions src/state/opamSwitchState.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ let slog = OpamConsole.slog

open OpamStateTypes

let load_selections ?lock_kind gt switch =
OpamStateConfig.Switch.safe_read_selections ?lock_kind gt switch
let load_selections ~lock_kind gt switch =
OpamStateConfig.Switch.safe_read_selections ~lock_kind gt switch

let load_switch_config ?lock_kind gt switch =
match OpamStateConfig.Switch.read_opt ?lock_kind gt switch with
let load_switch_config ~lock_kind gt switch =
match OpamStateConfig.Switch.read_opt ~lock_kind gt switch with
| Some c -> c
| exception (OpamPp.Bad_version _ as e) ->
OpamFormatUpgrade.hard_upgrade_from_2_1_intermediates
Expand Down Expand Up @@ -257,7 +257,7 @@ let load lock_kind gt rt switch =
OpamFilename.flock lock_kind (OpamPath.Switch.lock gt.root switch)
in
let switch_config = load_switch_config ~lock_kind gt switch in
if OpamStateConfig.is_newer_than_self gt then
if OpamStateConfig.is_newer_than_self ~lock_kind gt then
log "root version (%s) is greater than running binary's (%s); \
load with best-effort (read-only)"
(OpamVersion.to_string (OpamFile.Config.opam_root_version gt.config))
Expand Down Expand Up @@ -672,7 +672,8 @@ let drop st =
let _ = unlock st in ()

let with_write_lock ?dontblock st f =
if OpamStateConfig.is_newer_than_self st.switch_global then
if OpamStateConfig.is_newer_than_self ~lock_kind:`Lock_write st.switch_global
then
OpamConsole.error_and_exit `Locked
"The opam root has been upgraded by a newer version of opam-state \
and cannot be written to";
Expand Down
2 changes: 1 addition & 1 deletion src/state/opamSwitchState.mli
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ val load_virtual:
(** Load the switch's state file, without constructing the package maps: much
faster than loading the full switch state *)
val load_selections:
?lock_kind: 'a lock -> 'b global_state -> switch -> switch_selections
lock_kind: 'a lock -> 'b global_state -> switch -> switch_selections

(** Raw function to compute the availability of all packages, in [opams], given
the switch configuration and the set of pinned packages. (The result is
Expand Down

0 comments on commit ca23d8e

Please sign in to comment.