@@ -90,7 +90,16 @@ module File = struct
9090 ;;
9191end
9292
93- type db = File .t list
93+ type op =
94+ | File of File .t
95+ | Delete of Path.Source .t
96+
97+ let dyn_of_op = function
98+ | File f -> Dyn. variant " File" [ File. to_dyn f ]
99+ | Delete d -> Dyn. variant " Delete" [ Path.Source. to_dyn d ]
100+ ;;
101+
102+ type db = op list
94103
95104let db : db ref = ref []
96105let clear_cache () = db := []
@@ -100,7 +109,7 @@ let register_dep ~source_file ~correction_file =
100109 let src = snd (Path.Build. split_sandbox_root correction_file) in
101110 Dune_trace. emit Promote (fun () ->
102111 Dune_trace.Event.Promote. register `Direct src source_file);
103- db := { src; staging = None ; dst = source_file } :: ! db
112+ db := File { src; staging = None ; dst = source_file } :: ! db
104113;;
105114
106115let register_intermediate ~source_file ~correction_file =
@@ -110,28 +119,30 @@ let register_intermediate ~source_file ~correction_file =
110119 let staging = File. in_staging_area source_file in
111120 Path. mkdir_p (Path. build (Option. value_exn (Path.Build. parent staging)));
112121 Unix. rename (Path.Build. to_string correction_file) (Path.Build. to_string staging);
113- db := { src; staging = Some staging; dst = source_file } :: ! db
122+ db := File { src; staging = Some staging; dst = source_file } :: ! db
114123;;
115124
116125module P = Persistent. Make (struct
117- type t = File .t list
126+ type t = db
118127
119128 let name = " TO-PROMOTE"
120- let version = 3
121- let to_dyn = Dyn. list File. to_dyn
129+ let version = 4
130+ let to_dyn = Dyn. list dyn_of_op
122131
123132 let test_example () =
124- [ { File. src = Path.Build. (relative root " foo" )
125- ; dst = Path.Source. of_string " bar"
126- ; staging = Some Path.Build. (relative root " baz" )
127- }
133+ [ File
134+ { File. src = Path.Build. (relative root " foo" )
135+ ; dst = Path.Source. of_string " bar"
136+ ; staging = Some Path.Build. (relative root " baz" )
137+ }
138+ ; Delete (Path.Source. of_string " foo" )
128139 ]
129140 ;;
130141 end )
131142
132143let db_file = Path. relative Path. build_dir " .to-promote"
133144
134- let dump_db db =
145+ let dump_db ( db : db ) =
135146 if Path. build_dir_exists ()
136147 then (
137148 match db with
@@ -143,43 +154,54 @@ let dump_db db =
143154let load_db () = Option. value ~default: [] (P. load db_file)
144155
145156let group_by_targets db =
146- List. map db ~f: (fun { File. src; staging; dst } -> dst, (src, staging))
157+ List. map db ~f: (fun op ->
158+ match op with
159+ | Delete f -> f, `Delete
160+ | File { File. src; staging; dst } -> dst, `Promote (src, staging))
147161 |> Path.Source.Map. of_list_multi
148162 (* Sort the list of possible sources for deterministic behavior *)
149- |> Path.Source.Map. map
150- ~f: (List. sort ~compare: (fun (x , _ ) (y , _ ) -> Path.Build. compare x y))
163+ |> Path.Source.Map. map ~f: (List. sort ~compare: Poly. compare)
151164;;
152165
153166let promote_one dst srcs =
154167 match srcs with
155168 | [] -> assert false
156- | ( src , staging ) :: others ->
169+ | op :: others ->
157170 (* We used to remove promoted files from the digest cache, to force Dune
158- to redigest them on the next run. We did this because on OSX [mtime] is
159- not precise enough and if a file is modified and promoted quickly, it
160- looked like it hadn't changed even though it might have.
161-
162- aalekseyev: This is probably unnecessary now, depending on when
163- [do_promote] runs (before or after [invalidate_cached_timestamps]).
164-
165- amokhov: I removed this logic. In the current state of the world, files
166- in the build directory should be redigested automatically (plus we do
167- not promote into the build directory anyway), and source digests should
168- be correctly invalidated via [fs_memo]. If that doesn't happen, we
169- should fix [fs_memo] instead of manually resetting the caches here. *)
170- File. promote { src; staging; dst };
171- List. iter others ~f: (fun (path , _staging ) ->
171+ to redigest them on the next run. We did this because on OSX [mtime] is
172+ not precise enough and if a file is modified and promoted quickly, it
173+ looked like it hadn't changed even though it might have.
174+
175+ aalekseyev: This is probably unnecessary now, depending on when
176+ [do_promote] runs (before or after [invalidate_cached_timestamps]).
177+
178+ amokhov: I removed this logic. In the current state of the world, files
179+ in the build directory should be redigested automatically (plus we do
180+ not promote into the build directory anyway), and source digests should
181+ be correctly invalidated via [fs_memo]. If that doesn't happen, we
182+ should fix [fs_memo] instead of manually resetting the caches here. *)
183+ (match op with
184+ | `Promote (src , staging ) -> File. promote { src; staging; dst }
185+ | `Delete -> Unix. unlink (Path.Source. to_string dst));
186+ List. iter others ~f: (fun op ->
187+ let path =
188+ match op with
189+ | `Promote (src , _ ) -> Path. build src
190+ | `Delete -> Path. source dst
191+ in
172192 Console. print
173- [ Pp. textf " -> ignored %s." (Path. to_string_maybe_quoted (Path. build path))
174- ; Pp. space
175- ])
193+ [ Pp. textf " -> ignored %s." (Path. to_string_maybe_quoted path); Pp. space ])
176194;;
177195
178196let do_promote_all db = group_by_targets db |> Path.Source.Map. iteri ~f: promote_one
179197
180198let do_promote_these db files =
181199 let by_targets = group_by_targets db in
182- let by_targets, missing =
200+ let ( (by_targets :
201+ [> `Delete | `Promote of Path.Build. t * Path.Build. t option ] list
202+ Path.Source.Map. t)
203+ , missing )
204+ =
183205 let files = Path.Source.Set. of_list files in
184206 Path.Source.Set. fold files ~init: (by_targets, [] ) ~f: (fun fn (map , missing ) ->
185207 match Path.Source.Map. find map fn with
@@ -190,8 +212,10 @@ let do_promote_these db files =
190212 in
191213 let remaining =
192214 Path.Source.Map. to_list by_targets
193- |> List. concat_map ~f: (fun (dst , srcs ) ->
194- List. map srcs ~f: (fun (src , staging ) -> { File. src; staging; dst }))
215+ |> List. concat_map ~f: (fun (dst , ops ) ->
216+ List. map ops ~f: (function
217+ | `Delete -> Delete dst
218+ | `Promote (src , staging ) -> File { File. src; staging; dst }))
195219 in
196220 (* [group_by_targets] will sort all files, but the [fold] above reverses
197221 the list of missing files. Here we re-reverse it so it is sorted.
@@ -236,7 +260,13 @@ type all =
236260(* * [partition_db db files_to_promote] splits [files_to_promote] into two lists
237261 - The files present in [db] as actual [File.t]s.
238262 - The files absent from [db] as [Path]s. *)
239- let partition_db db files_to_promote =
263+ let partition_db (db : db ) files_to_promote =
264+ let db =
265+ (* CR-soon rgrinberg: communicate deletions to the user *)
266+ List. filter_map db ~f: (function
267+ | File f -> Some f
268+ | Delete _ -> None )
269+ in
240270 let present, missing =
241271 match files_to_promote with
242272 | Files_to_promote. All -> db, []
@@ -248,3 +278,5 @@ let partition_db db files_to_promote =
248278 in
249279 { present; missing }
250280;;
281+
282+ let register_delete src = db := Delete src :: ! db
0 commit comments