Skip to content

Commit 0442b11

Browse files
authored
Merge pull request #11541 from ocaml/digest-no-perm
Cache: only store executable permission bit
2 parents 5033aa6 + 4140e38 commit 0442b11

File tree

5 files changed

+18
-20
lines changed

5 files changed

+18
-20
lines changed

doc/changes/11541.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Cache: we now only store the executable permission bit for files (#11541, fixes #11533, @ElectreAAS)

src/dune_digest/digest.ml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,13 @@ let file_with_executable_bit ~executable path =
9191
module Stats_for_digest = struct
9292
type t =
9393
{ st_kind : Unix.file_kind
94-
; st_perm : Unix.file_perm
94+
; executable : bool
9595
}
9696

9797
let of_unix_stats (stats : Unix.stats) =
98-
{ st_kind = stats.st_kind; st_perm = stats.st_perm }
98+
(* Check if any of the +x bits are set, ignore read and write *)
99+
let executable = 0o111 land stats.st_perm <> 0 in
100+
{ st_kind = stats.st_kind; executable }
99101
;;
100102
end
101103

@@ -113,17 +115,15 @@ let path_with_stats ~allow_dirs path (stats : Stats_for_digest.t) =
113115
let rec loop path (stats : Stats_for_digest.t) =
114116
match stats.st_kind with
115117
| S_LNK ->
116-
let executable = Path.Permissions.test Path.Permissions.execute stats.st_perm in
117118
Dune_filesystem_stubs.Unix_error.Detailed.catch
118119
(fun path ->
119120
let contents = Unix.readlink (Path.to_string path) in
120-
path_with_executable_bit ~executable ~content_digest:contents)
121+
path_with_executable_bit ~executable:stats.executable ~content_digest:contents)
121122
path
122123
|> Result.map_error ~f:(fun x -> Path_digest_error.Unix_error x)
123124
| S_REG ->
124-
let executable = Path.Permissions.test Path.Permissions.execute stats.st_perm in
125125
Dune_filesystem_stubs.Unix_error.Detailed.catch
126-
(file_with_executable_bit ~executable)
126+
(file_with_executable_bit ~executable:stats.executable)
127127
path
128128
|> Result.map_error ~f:(fun x -> Path_digest_error.Unix_error x)
129129
| S_DIR when allow_dirs ->
@@ -150,7 +150,8 @@ let path_with_stats ~allow_dirs path (stats : Stats_for_digest.t) =
150150
|> List.sort ~compare:(fun (x, _) (y, _) -> String.compare x y)
151151
with
152152
| exception E e -> Error e
153-
| contents -> Ok (generic (directory_digest_version, contents, stats.st_perm))))
153+
| contents ->
154+
Ok (generic (directory_digest_version, contents, stats.executable))))
154155
| S_DIR | S_BLK | S_CHR | S_FIFO | S_SOCK -> Error Unexpected_kind
155156
in
156157
match stats.st_kind with

src/dune_digest/digest.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ val generic : 'a -> t
2424
module Stats_for_digest : sig
2525
type t =
2626
{ st_kind : Unix.file_kind
27-
; st_perm : Unix.file_perm
27+
; executable : bool
2828
}
2929

3030
val of_unix_stats : Unix.stats -> t

test/blackbox-tests/test-cases/directory-targets/cache-permissions.t

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,16 @@ First build: `d` (with mode 755) and `other` are stored in cache
3737
$ dune build other
3838
building d
3939
building other
40+
41+
The chmod command was run, so this is expected
4042
$ dune_cmd stat permissions _build/default/d
4143
755
4244

43-
Second build: `d` is restored but the cached `other` depends on a version of
44-
`d` that does not correspond to what's in `_build`, so `other` gets rebuilt.
45-
Both versions are stored.
45+
Second build: `d` is restored and `other` can use it, so no rebuild happens.
4646

4747
$ dune clean
4848
$ dune build other
49-
building other
49+
50+
We'll note that the permissions are still set to the umask
5051
$ dune_cmd stat permissions _build/default/d
5152
775
52-
53-
Third build: `d` is restored and `other` can use it, so no rebuild happens.
54-
55-
$ dune clean
56-
$ dune build other

test/expect-tests/digest/digest_tests.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ open Stdune
22
module Digest = Dune_digest
33

44
let%expect_test "directory digest version" =
5-
(* If this test fails with a new digest value, make sure to update to update
5+
(* If this test fails with a new digest value, make sure to update
66
[directory_digest_version] in digest.ml.
77
88
The expected value is kept outside of the expect block on purpose so that it
99
must be modified manually. *)
1010
let expected = "a743ec66ce913ff6587a3816a8acc6ea" in
1111
let dir = Temp.create Dir ~prefix:"digest-tests" ~suffix:"" in
12-
let stats = { Digest.Stats_for_digest.st_kind = S_DIR; st_perm = 1 } in
12+
let stats = { Digest.Stats_for_digest.st_kind = S_DIR; executable = true } in
1313
(match Digest.path_with_stats ~allow_dirs:true dir stats with
1414
| Ok digest ->
1515
let digest = Digest.to_string digest in
@@ -26,7 +26,7 @@ let%expect_test "directory digest version" =
2626

2727
let%expect_test "directories with symlinks" =
2828
let dir = Temp.create Dir ~prefix:"digest-tests" ~suffix:"" in
29-
let stats = { Digest.Stats_for_digest.st_kind = S_DIR; st_perm = 1 } in
29+
let stats = { Digest.Stats_for_digest.st_kind = S_DIR; executable = true } in
3030
let sub = Path.relative dir "sub" in
3131
Path.mkdir_p sub;
3232
Unix.symlink "bar" (Path.to_string (Path.relative dir "foo"));

0 commit comments

Comments
 (0)