Skip to content
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
3 changes: 3 additions & 0 deletions doc/changes/fixed/13713.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Fix the Dune cache on Windows by correctly handling renames onto read-only
files. Before this change, the Dune cache would be filled but the stored
artifacts would not generally be usable by Dune. (#13713, @Nevor)
17 changes: 17 additions & 0 deletions otherlibs/stdune/src/fpath.ml
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,23 @@ let unlink_exn ~chmod dir fn =
unlink_exn_ignore_missing fn
;;

let win32_rename_exn src dst =
match Unix.rename src dst with
| () -> ()
| exception Unix.Unix_error (Unix.EACCES, _, _) ->
(* Try removing the read-only attribute.
Workaround a behavior discrepancy between Unix and Windows of the
[Unix.rename] function. It accepts readonly override on Unix but not
on Windows. This discrepancy will be fixed in OCaml 5.6 which will
include https://github.com/ocaml/ocaml/pull/14602 *)
Unix.chmod dst 0o666;
Unix.rename src dst
;;

let rename_exn =
if Stdlib.Sys.win32 then fun x y -> win32_rename_exn x y else fun x y -> Unix.rename x y
;;

let rec clear_dir ?(chmod = false) dir =
match
match Readdir.read_directory_with_kinds dir with
Expand Down
1 change: 1 addition & 0 deletions otherlibs/stdune/src/fpath.mli
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type unlink_status =
(** Unlink and return error, if any. *)
val unlink : string -> unlink_status

val rename_exn : string -> string -> unit
val initial_cwd : string

type clear_dir_result =
Expand Down
2 changes: 1 addition & 1 deletion src/dune_cache/local.ml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ module Artifacts = struct
[rename] operation has a quirk where [path_in_temp_dir] can
remain on disk. This is not a problem because we clean the
temporary directory later. *)
Unix.rename
Fpath.rename_exn
(Path.to_string path_in_temp_dir)
(Path.to_string path_in_build_dir)
with
Expand Down
Loading