File tree Expand file tree Collapse file tree 3 files changed +43
-3
lines changed Expand file tree Collapse file tree 3 files changed +43
-3
lines changed Original file line number Diff line number Diff line change @@ -72,7 +72,9 @@ let open_out ~sw ?(append=false) ~create t =
72
72
let open_dir ~sw t =
73
73
let (Resource. T (dir, ops), path) = t in
74
74
let module X = (val (Resource. get ops Fs.Pi. Dir )) in
75
- try X. open_dir dir ~sw path, " "
75
+ try
76
+ let sub = X. open_dir dir ~sw path, " " in
77
+ (sub : [`Close | `Dir] t :> [< `Close | `Dir] t )
76
78
with Exn. Io _ as ex ->
77
79
let bt = Printexc. get_raw_backtrace () in
78
80
Exn. reraise_with_context ex bt " opening directory %a" pp t
@@ -163,6 +165,19 @@ let rmdir t =
163
165
let bt = Printexc. get_raw_backtrace () in
164
166
Exn. reraise_with_context ex bt " removing directory %a" pp t
165
167
168
+ let rec rmtree (t : Fs.dir_ty t ) =
169
+ with_open_dir t (fun t ->
170
+ read_dir t |> List. iter (fun name ->
171
+ let item = t / name in
172
+ match kind ~follow: false item with
173
+ | `Directory -> rmtree item
174
+ | _ -> unlink item
175
+ )
176
+ );
177
+ rmdir t
178
+
179
+ let rmtree = (rmtree : Fs.dir_ty t -> unit :> [> Fs.dir_ty] t -> unit )
180
+
166
181
let rename t1 t2 =
167
182
let (dir2, new_path) = t2 in
168
183
let (Resource. T (dir, ops), old_path) = t1 in
Original file line number Diff line number Diff line change @@ -139,12 +139,12 @@ val mkdirs : ?exists_ok:bool -> perm:File.Unix_perm.t -> _ t -> unit
139
139
140
140
@param exist_ok If [false] (the default) then we raise {! Fs.Already_exists} if [t] is already a directory. *)
141
141
142
- val open_dir : sw :Switch .t -> _ t -> [`Close | dir_ty ] t
142
+ val open_dir : sw :Switch .t -> _ t -> [< `Close | dir_ty ] t
143
143
(* * [open_dir ~sw t] opens [t].
144
144
145
145
This can be passed to functions to grant access only to the subtree [t]. *)
146
146
147
- val with_open_dir : _ t -> ([`Close | dir_ty ] t -> 'a ) -> 'a
147
+ val with_open_dir : _ t -> ([< `Close | dir_ty ] t -> 'a ) -> 'a
148
148
(* * [with_open_dir] is like [open_dir], but calls [fn dir] with the new directory and closes
149
149
it automatically when [fn] returns (if it hasn't already been closed by then). *)
150
150
@@ -192,6 +192,9 @@ val rmdir : _ t -> unit
192
192
193
193
Note: this usually requires the directory to be empty. *)
194
194
195
+ val rmtree : _ t -> unit
196
+ (* * [rmtree t] removes directory [t] and its contents, recursively. *)
197
+
195
198
val rename : _ t -> _ t -> unit
196
199
(* * [rename old_t new_t] atomically unlinks [old_t] and links it as [new_t].
197
200
Original file line number Diff line number Diff line change @@ -61,6 +61,11 @@ let try_rmdir path =
61
61
| () -> traceln "rmdir %a -> ok" Path.pp path
62
62
| exception ex -> traceln "@[<h>%a@]" Eio.Exn.pp ex
63
63
64
+ let try_rmtree path =
65
+ match Path.rmtree path with
66
+ | () -> traceln "rmtree %a -> ok" Path.pp path
67
+ | exception ex -> traceln "@[<h>%a@]" Eio.Exn.pp ex
68
+
64
69
let chdir path =
65
70
traceln "chdir %S" path;
66
71
Unix.chdir path
@@ -397,6 +402,23 @@ Removing something that doesn't exist or is out of scope:
397
402
- : unit = ()
398
403
```
399
404
405
+ # Recursive removal
406
+
407
+ ``` ocaml
408
+ # run @@ fun env ->
409
+ Switch.run @@ fun sw ->
410
+ let cwd = Eio.Stdenv.cwd env in
411
+ let foo = cwd / "foo" in
412
+ try_mkdirs (foo / "bar"/ "baz");
413
+ try_write_file ~create:(`Exclusive 0o600) (foo / "bar/file1") "data";
414
+ try_rmtree foo;
415
+ assert (Path.kind ~follow:false foo = `Not_found);
416
+ +mkdirs <cwd:foo/bar/baz> -> ok
417
+ +write <cwd:foo/bar/file1> -> ok
418
+ +rmtree <cwd:foo> -> ok
419
+ - : unit = ()
420
+ ```
421
+
400
422
# Limiting to a subdirectory
401
423
402
424
Create a sandbox, write a file with it, then read it from outside:
You can’t perform that action at this time.
0 commit comments