@@ -185,34 +185,51 @@ let lockdir_status dev_tool =
185185 (match Lock_dir. read_disk dev_tool_lock_dir with
186186 | Error _ -> Memo. return `No_lockdir
187187 | Ok { packages; _ } ->
188- (match Dune_pkg.Dev_tool. needs_to_build_with_same_compiler_as_project dev_tool with
189- | false -> Memo. return `Lockdir_ok
190- | true ->
191- let * platform =
192- Pkg.Pkg_common. poll_solver_env_from_current_system ()
193- |> Memo. of_reproducible_fiber
194- in
195- let packages = Lock_dir.Packages. pkgs_on_platform_by_name packages ~platform in
196- (match Package_name.Map. find packages compiler_package_name with
197- | None -> Memo. return `No_compiler_lockfile_in_lockdir
198- | Some { info; _ } ->
199- let + ocaml_compiler_version = locked_ocaml_compiler_version () in
200- (match Package_version. equal info.version ocaml_compiler_version with
201- | true -> `Lockdir_ok
202- | false ->
203- `Dev_tool_needs_to_be_relocked_because_project_compiler_version_changed
204- (User_message. make
205- [ Pp. textf
206- " The version of the compiler package (%S) in this project's \
207- lockdir has changed to %s (formerly the compiler version was \
208- %s). The dev-tool %S will be re-locked and rebuilt with this \
209- version of the compiler."
210- (Package_name. to_string compiler_package_name)
211- (Package_version. to_string ocaml_compiler_version)
212- (Package_version. to_string info.version)
213- (Dune_pkg.Dev_tool. package_name dev_tool
214- |> Package_name. to_string)
215- ])))))
188+ let * platform =
189+ Pkg.Pkg_common. poll_solver_env_from_current_system ()
190+ |> Memo. of_reproducible_fiber
191+ in
192+ let packages = Lock_dir.Packages. pkgs_on_platform_by_name packages ~platform in
193+ let package_name = Dune_pkg.Dev_tool. package_name dev_tool in
194+ (match Package_name.Map. find packages package_name with
195+ | None ->
196+ Memo. return
197+ (`Lockdir_missing_entry_for_tool
198+ (User_message. make
199+ [ Pp. textf
200+ " The lock directory for the tool %S exists but does not contain a \
201+ lockfile for the package %S. This may indicate that the lock \
202+ directory has been tampered with. Please avoid making manual \
203+ changes to tool lock directories. The tool will now be relocked."
204+ (Dune_pkg.Dev_tool. exe_name dev_tool)
205+ (Package_name. to_string package_name)
206+ ]))
207+ | Some pkg ->
208+ (match
209+ Dune_pkg.Dev_tool. needs_to_build_with_same_compiler_as_project dev_tool
210+ with
211+ | false -> Memo. return (`Lockdir_ok_with_tool_pkg pkg)
212+ | true ->
213+ (match Package_name.Map. find packages compiler_package_name with
214+ | None -> Memo. return `No_compiler_lockfile_in_lockdir
215+ | Some { info; _ } ->
216+ let + ocaml_compiler_version = locked_ocaml_compiler_version () in
217+ (match Package_version. equal info.version ocaml_compiler_version with
218+ | true -> `Lockdir_ok_with_tool_pkg pkg
219+ | false ->
220+ `Dev_tool_needs_to_be_relocked_because_project_compiler_version_changed
221+ (User_message. make
222+ [ Pp. textf
223+ " The version of the compiler package (%S) in this project's \
224+ lockdir has changed to %s (formerly the compiler version \
225+ was %s). The dev-tool %S will be re-locked and rebuilt with \
226+ this version of the compiler."
227+ (Package_name. to_string compiler_package_name)
228+ (Package_version. to_string ocaml_compiler_version)
229+ (Package_version. to_string info.version)
230+ (Dune_pkg.Dev_tool. package_name dev_tool
231+ |> Package_name. to_string)
232+ ]))))))
216233;;
217234
218235(* [lock_dev_tool_at_version dev_tool version] generates the lockdir for the
@@ -224,7 +241,28 @@ let lock_dev_tool_at_version dev_tool version =
224241 let * need_to_solve =
225242 lockdir_status dev_tool
226243 >> | function
227- | `Lockdir_ok -> false
244+ | `Lockdir_ok_with_tool_pkg (pkg : Dune_pkg.Lock_dir.Pkg.t ) ->
245+ (match version with
246+ | None -> false
247+ | Some version ->
248+ (* If this function was passed a specific version, and the dev
249+ tool's lockfile contains a different version from the specified
250+ version, regenerate the lockdir. *)
251+ let different_version_currently_locked =
252+ not (Package_version. equal pkg.info.version version)
253+ in
254+ if different_version_currently_locked
255+ then
256+ Console. print
257+ [ Pp. textf
258+ " The lock directory for the tool %S exists but contains a solution for \
259+ %s of the tool, whereas version %s now needs to be installed. The tool \
260+ will now be re-locked."
261+ (Dune_pkg.Dev_tool. exe_name dev_tool)
262+ (Package_version. to_string pkg.info.version)
263+ (Package_version. to_string version)
264+ ];
265+ different_version_currently_locked)
228266 | `No_lockdir -> true
229267 | `No_compiler_lockfile_in_lockdir ->
230268 Console. print
@@ -237,6 +275,9 @@ let lock_dev_tool_at_version dev_tool version =
237275 | `Dev_tool_needs_to_be_relocked_because_project_compiler_version_changed message ->
238276 Console. print_user_message message;
239277 true
278+ | `Lockdir_missing_entry_for_tool message ->
279+ User_warning. emit_message message;
280+ true
240281 in
241282 if need_to_solve
242283 then
0 commit comments