|
|
|
let readdir = dir => {
|
|
|
|
let items = ref([]);
|
|
|
|
let%lwt dir = Lwt_unix.opendir(dir);
|
|
|
|
let iterate = () => {
|
|
|
|
let%lwt _ =
|
|
|
|
while%lwt (true) {
|
|
|
|
let%lwt value = Lwt_unix.readdir(dir);
|
|
|
|
if (value.[0] != '.') {
|
|
|
|
items := [value, ...items^];
|
|
|
|
};
|
|
|
|
Lwt.return();
|
|
|
|
};
|
|
|
|
|
|
|
|
Lwt.return([]);
|
|
|
|
};
|
|
|
|
|
|
|
|
let%lwt items =
|
|
|
|
try%lwt (iterate()) {
|
|
|
|
| End_of_file => Lwt.return(items^)
|
|
|
|
};
|
|
|
|
|
|
|
|
let%lwt _ = Lwt_unix.closedir(dir);
|
|
|
|
Lwt.return(items);
|
|
|
|
};
|
|
|
|
|
|
|
|
let writeFile = (path, contents) => {
|
|
|
|
let%lwt targetFile = Lwt_io.open_file(~mode=Lwt_io.Output, path);
|
|
|
|
|
|
|
|
let%lwt () = Lwt_io.write(targetFile, contents);
|
|
|
|
let%lwt () = Lwt_io.close(targetFile);
|
|
|
|
|
|
|
|
Lwt.return();
|
|
|
|
};
|
|
|
|
|
|
|
|
let exists = path => {
|
|
|
|
try%lwt (Lwt_unix.file_exists(path)) {
|
|
|
|
| Unix.Unix_error(_, _, _) => Lwt.return(false)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let readlink = path =>
|
|
|
|
try%lwt (Lwt_unix.readlink(path) |> Lwt.map(x => Ok(x))) {
|
|
|
|
| err => Lwt.return_error(err)
|
|
|
|
};
|
|
|
|
|
|
|
|
[@deriving show]
|
|
|
|
type file_type =
|
|
|
|
| File(string)
|
|
|
|
| Dir(string);
|
|
|
|
|
|
|
|
// Based on: https://github.com/fastpack/fastpack/blob/9f6aa7d5b83ffef03e73a15679200576ff9dbcb7/FastpackUtil/FS.re#L94
|
|
|
|
let rec listDirRecursively = dir => {
|
|
|
|
switch%lwt (Lwt_unix.lstat(dir)) {
|
|
|
|
| {st_kind: Lwt_unix.S_DIR, _} =>
|
|
|
|
Lwt_unix.files_of_directory(dir)
|
|
|
|
|> Lwt_stream.map_list_s(
|
|
|
|
fun
|
|
|
|
| "."
|
|
|
|
| ".." => Lwt.return([])
|
|
|
|
| filename => Filename.concat(dir, filename) |> listDirRecursively,
|
|
|
|
)
|
|
|
|
|> Lwt_stream.to_list
|
|
|
|
|> Lwt.map(xs => List.append(xs, [Dir(dir)]))
|
|
|
|
| _ => Lwt.return([File(dir)])
|
|
|
|
| exception (Unix.Unix_error(Unix.ENOENT, _, _)) => Lwt.return([])
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let rmdir = dir => {
|
|
|
|
let%lwt entities = listDirRecursively(dir);
|
|
|
|
|
|
|
|
entities
|
|
|
|
|> Lwt_list.map_s(
|
|
|
|
fun
|
|
|
|
| Dir(dir) => Lwt_unix.rmdir(dir)
|
|
|
|
| File(file) => Lwt_unix.unlink(file),
|
|
|
|
)
|
|
|
|
|> Lwt.map(_ => ());
|
|
|
|
};
|
|
|
|
|
|
|
|
type path =
|
|
|
|
| Exists(string)
|
|
|
|
| Missing(string);
|
|
|
|
|
|
|
|
let rec realpath = path => {
|
|
|
|
switch%lwt (readlink(path)) {
|
|
|
|
| Ok(path) => realpath(path)
|
|
|
|
| Error(_) =>
|
|
|
|
switch%lwt (exists(path)) {
|
|
|
|
| true => Exists(path) |> Lwt.return
|
|
|
|
| false => Missing(path) |> Lwt.return
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|