Skip to content

Commit 28fe966

Browse files
authored
Return [result] when loading lockdir (#10847)
Adds versions of functions that load lockdirs that return [Error] when loading fails rather than raising an exception. Signed-off-by: Stephen Sherratt <[email protected]>
1 parent 5607dd9 commit 28fe966

File tree

6 files changed

+95
-74
lines changed

6 files changed

+95
-74
lines changed

src/dune_pkg/lock_dir.ml

+73-60
Original file line numberDiff line numberDiff line change
@@ -634,32 +634,35 @@ struct
634634
let open Io.O in
635635
Io.stats_kind lock_dir_path
636636
>>| function
637-
| Ok S_DIR -> ()
637+
| Ok S_DIR -> Ok ()
638638
| Error (Unix.ENOENT, _, _) ->
639-
User_error.raise
640-
~hints:
641-
[ Pp.concat
642-
~sep:Pp.space
643-
[ Pp.text "Run"
644-
; User_message.command "dune pkg lock"
645-
; Pp.text "to generate it."
646-
]
647-
|> Pp.hovbox
648-
]
649-
[ Pp.textf "%s does not exist." (Path.Source.to_string lock_dir_path) ]
639+
Error
640+
(User_error.make
641+
~hints:
642+
[ Pp.concat
643+
~sep:Pp.space
644+
[ Pp.text "Run"
645+
; User_message.command "dune pkg lock"
646+
; Pp.text "to generate it."
647+
]
648+
|> Pp.hovbox
649+
]
650+
[ Pp.textf "%s does not exist." (Path.Source.to_string lock_dir_path) ])
650651
| Error e ->
651-
User_error.raise
652-
[ Pp.textf "%s is not accessible" (Path.Source.to_string lock_dir_path)
653-
; Pp.textf "reason: %s" (Unix_error.Detailed.to_string_hum e)
654-
]
652+
Error
653+
(User_error.make
654+
[ Pp.textf "%s is not accessible" (Path.Source.to_string lock_dir_path)
655+
; Pp.textf "reason: %s" (Unix_error.Detailed.to_string_hum e)
656+
])
655657
| _ ->
656-
User_error.raise
657-
[ Pp.textf "%s is not a directory." (Path.Source.to_string lock_dir_path) ]
658+
Error
659+
(User_error.make
660+
[ Pp.textf "%s is not a directory." (Path.Source.to_string lock_dir_path) ])
658661
;;
659662

660663
let check_packages packages ~lock_dir_path =
661664
match validate_packages packages with
662-
| Ok () -> ()
665+
| Ok () -> Ok ()
663666
| Error (`Missing_dependencies missing_dependencies) ->
664667
List.iter missing_dependencies ~f:(fun { dependant_package; dependency; loc } ->
665668
User_message.prerr
@@ -673,50 +676,60 @@ struct
673676
(Package_name.to_string dependency)
674677
(Path.Source.to_string_maybe_quoted lock_dir_path)
675678
]));
676-
User_error.raise
677-
~hints:
678-
[ Pp.concat
679-
~sep:Pp.space
680-
[ Pp.text
681-
"This could indicate that the lockdir is corrupted. Delete it and then \
682-
regenerate it by running:"
683-
; User_message.command "dune pkg lock"
684-
]
685-
]
686-
[ Pp.textf
687-
"At least one package dependency is itself not present as a package in the \
688-
lockdir %s."
689-
(Path.Source.to_string_maybe_quoted lock_dir_path)
690-
]
679+
Error
680+
(User_error.make
681+
~hints:
682+
[ Pp.concat
683+
~sep:Pp.space
684+
[ Pp.text
685+
"This could indicate that the lockdir is corrupted. Delete it and \
686+
then regenerate it by running:"
687+
; User_message.command "dune pkg lock"
688+
]
689+
]
690+
[ Pp.textf
691+
"At least one package dependency is itself not present as a package in \
692+
the lockdir %s."
693+
(Path.Source.to_string_maybe_quoted lock_dir_path)
694+
])
691695
;;
692696

693697
let load lock_dir_path =
694698
let open Io.O in
695-
let* () = check_path lock_dir_path in
696-
let* version, dependency_hash, ocaml, repos, expanded_solver_variable_bindings =
697-
load_metadata (Path.Source.relative lock_dir_path metadata_filename)
698-
in
699-
let+ packages =
700-
Io.readdir_with_kinds lock_dir_path
701-
>>| List.filter_map ~f:(fun (name, (kind : Unix.file_kind)) ->
702-
match kind with
703-
| S_REG -> Package_filename.to_package_name name |> Result.to_option
704-
| _ ->
705-
(* TODO *)
706-
None)
707-
>>= Io.parallel_map ~f:(fun package_name ->
708-
let+ pkg = load_pkg ~version ~lock_dir_path package_name in
709-
package_name, pkg)
710-
>>| Package_name.Map.of_list_exn
711-
in
712-
check_packages packages ~lock_dir_path;
713-
{ version
714-
; dependency_hash
715-
; packages
716-
; ocaml
717-
; repos
718-
; expanded_solver_variable_bindings
719-
}
699+
let* result = check_path lock_dir_path in
700+
match result with
701+
| Error e -> Io.return (Error e)
702+
| Ok () ->
703+
let* version, dependency_hash, ocaml, repos, expanded_solver_variable_bindings =
704+
load_metadata (Path.Source.relative lock_dir_path metadata_filename)
705+
in
706+
let+ packages =
707+
Io.readdir_with_kinds lock_dir_path
708+
>>| List.filter_map ~f:(fun (name, (kind : Unix.file_kind)) ->
709+
match kind with
710+
| S_REG -> Package_filename.to_package_name name |> Result.to_option
711+
| _ ->
712+
(* TODO *)
713+
None)
714+
>>= Io.parallel_map ~f:(fun package_name ->
715+
let+ pkg = load_pkg ~version ~lock_dir_path package_name in
716+
package_name, pkg)
717+
>>| Package_name.Map.of_list_exn
718+
in
719+
check_packages packages ~lock_dir_path
720+
|> Result.map ~f:(fun () ->
721+
{ version
722+
; dependency_hash
723+
; packages
724+
; ocaml
725+
; repos
726+
; expanded_solver_variable_bindings
727+
})
728+
;;
729+
730+
let load_exn lock_dir_path =
731+
let open Io.O in
732+
load lock_dir_path >>| User_error.ok_exn
720733
;;
721734
end
722735

@@ -740,7 +753,7 @@ module Load_immediate = Make_load (struct
740753
let with_lexbuf_from_file path ~f = Io.with_lexbuf_from_file (Path.source path) ~f
741754
end)
742755

743-
let read_disk = Load_immediate.load
756+
let read_disk = Load_immediate.load_exn
744757

745758
let transitive_dependency_closure t start =
746759
let missing_packages =

src/dune_pkg/lock_dir.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ module Make_load (Io : sig
100100
val with_lexbuf_from_file : Path.Source.t -> f:(Lexing.lexbuf -> 'a) -> 'a t
101101
val stats_kind : Path.Source.t -> (File_kind.t, Unix_error.Detailed.t) result t
102102
end) : sig
103-
val load : Path.Source.t -> t Io.t
103+
val load : Path.Source.t -> (t, User_message.t) result Io.t
104+
val load_exn : Path.Source.t -> t Io.t
104105
end
105106

106107
(** [transitive_dependency_closure t names] returns the set of package names

src/dune_rules/fetch_rules.ml

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ let find_checksum, find_url =
158158
Memo.lazy_ (fun () ->
159159
Per_context.list ()
160160
>>= Memo.parallel_map ~f:Lock_dir.get
161+
>>| List.filter_map ~f:Result.to_option
161162
>>| List.fold_left
162163
~init:(Checksum.Map.empty, Digest.Map.empty)
163164
~f:(fun (checksums, urls) (lockdir : Dune_pkg.Lock_dir.t) ->

src/dune_rules/lock_dir.ml

+15-10
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,23 @@ let get_workspace_lock_dir ctx =
128128
Workspace.find_lock_dir workspace path
129129
;;
130130

131-
let get (ctx : Context_name.t) : t Memo.t =
132-
let* lock_dir = get_path ctx >>| Option.value_exn >>= Load.load in
133-
let+ workspace_lock_dir = get_workspace_lock_dir ctx in
134-
(match workspace_lock_dir with
135-
| None -> ()
136-
| Some workspace_lock_dir ->
137-
Solver_stats.Expanded_variable_bindings.validate_against_solver_env
138-
lock_dir.expanded_solver_variable_bindings
139-
(workspace_lock_dir.solver_env |> Option.value ~default:Solver_env.empty));
140-
lock_dir
131+
let get ctx =
132+
let* result = get_path ctx >>| Option.value_exn >>= Load.load in
133+
match result with
134+
| Error e -> Memo.return (Error e)
135+
| Ok lock_dir ->
136+
let+ workspace_lock_dir = get_workspace_lock_dir ctx in
137+
(match workspace_lock_dir with
138+
| None -> ()
139+
| Some workspace_lock_dir ->
140+
Solver_stats.Expanded_variable_bindings.validate_against_solver_env
141+
lock_dir.expanded_solver_variable_bindings
142+
(workspace_lock_dir.solver_env |> Option.value ~default:Solver_env.empty));
143+
Ok lock_dir
141144
;;
142145

146+
let get_exn ctx = get ctx >>| User_error.ok_exn
147+
143148
let lock_dir_active ctx =
144149
if !Clflags.ignore_lock_dir
145150
then Memo.return false

src/dune_rules/lock_dir.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module Pkg = Dune_pkg.Lock_dir.Pkg
33

44
type t := Dune_pkg.Lock_dir.t
55

6-
val get : Context_name.t -> t Memo.t
6+
val get : Context_name.t -> (t, User_message.t) result Memo.t
7+
val get_exn : Context_name.t -> t Memo.t
78
val lock_dir_active : Context_name.t -> bool Memo.t
89
val get_path : Context_name.t -> Path.Source.t option Memo.t
910

src/dune_rules/pkg_rules.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ module DB = struct
11351135
let get =
11361136
let dune = Package.Name.Set.singleton (Package.Name.of_string "dune") in
11371137
fun context ->
1138-
let+ all = Lock_dir.get context in
1138+
let+ all = Lock_dir.get_exn context in
11391139
{ all = all.packages; system_provided = dune }
11401140
;;
11411141
end
@@ -1872,7 +1872,7 @@ let setup_rules ~components ~dir ctx =
18721872
;;
18731873

18741874
let ocaml_toolchain context =
1875-
(let* lock_dir = Lock_dir.get context in
1875+
(let* lock_dir = Lock_dir.get_exn context in
18761876
let* db = DB.get context in
18771877
match lock_dir.ocaml with
18781878
| None -> Memo.return `System_provided

0 commit comments

Comments
 (0)