Browse Source

Do uninstallation in steps (#138)

Fixes #122, and adds tests for it:

The problem, I believe, was that some files were deleted before their symlink was deleted. `Unix.stat` fails on symlinks that point to missing files. We don't really care about their stat, honestly, so we can just run `Unix.lstat` and remove them.
remotes/origin/add-simple-redirecting-site
Gal Schlezinger 6 years ago committed by GitHub
parent
commit
8fca9214d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      library/Fs.re
  2. 1
      test/TestFnm.re
  3. 61
      test/TestFs.re

52
library/Fs.re

@ -43,25 +43,39 @@ let readlink = path =>
| err => Lwt.return_error(err) | err => Lwt.return_error(err)
}; };
// Credit: https://github.com/fastpack/fastpack/blob/9f6aa7d5b83ffef03e73a15679200576ff9dbcb7/FastpackUtil/FS.re#L94 [@deriving show]
let rec rmdir = dir => { type file_type =
let%lwt files = Lwt_unix.files_of_directory(dir) |> Lwt_stream.to_list; | File(string)
let%lwt () = | Dir(string);
Lwt_list.iter_s(
filename => // Based on: https://github.com/fastpack/fastpack/blob/9f6aa7d5b83ffef03e73a15679200576ff9dbcb7/FastpackUtil/FS.re#L94
switch (filename) { let rec listDirRecursively = dir => {
| "." switch%lwt (Lwt_unix.lstat(dir)) {
| ".." => Lwt.return_unit | {st_kind: Lwt_unix.S_DIR, _} =>
| _ => Lwt_unix.files_of_directory(dir)
let path = Filename.concat(dir, filename); |> Lwt_stream.map_list_s(
switch%lwt (Lwt_unix.stat(path)) { fun
| {st_kind: Lwt_unix.S_DIR, _} => rmdir(path) | "."
| _ => Lwt_unix.unlink(path) | ".." => Lwt.return([])
}; | filename => Filename.concat(dir, filename) |> listDirRecursively,
}, )
files, |> Lwt_stream.to_list
); |> Lwt.map(xs => List.append(xs, [Dir(dir)]))
Lwt_unix.rmdir(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 = type path =

1
test/TestFnm.re

@ -1,4 +1,5 @@
include SmokeTest; include SmokeTest;
include TestSemver; include TestSemver;
include TestFs;
TestFramework.cli(); TestFramework.cli();

61
test/TestFs.re

@ -0,0 +1,61 @@
open TestFramework;
open Fnm;
let get_tempdir = prefix => {
Printf.sprintf(
"fnm-test-%s-%s",
prefix,
Unix.time() |> int_of_float |> string_of_int,
)
|> Filename.concat(Filename.get_temp_dir_name());
};
describe("TestSemver", ({test, describe, _}) => {
describe("listDirRecursively", ({test, _}) => {
test("list files and directories", ({expect, _}) => {
let xs = Fs.listDirRecursively("feature_tests") |> Lwt_main.run;
expect.list(xs).toContainEqual(
Fs.File("feature_tests/multishell/run.sh"),
);
expect.list(xs).toContainEqual(Fs.Dir("feature_tests/multishell"));
expect.list(xs).toContainEqual(Fs.Dir("feature_tests"));
});
test("works with symlinks", ({expect, _}) => {
let tmpdir = get_tempdir("symlinks");
let fileDir = Filename.concat(tmpdir, "a/b/c/d/e/f/g");
let filePath = Filename.concat(fileDir, "file");
Sys.command("mkdir -p " ++ fileDir) |> ignore;
Sys.command("touch " ++ filePath) |> ignore;
Sys.command("ln -s " ++ filePath ++ " " ++ filePath ++ "_link")
|> ignore;
Sys.command(
"ln -s " ++ filePath ++ "_not_found " ++ filePath ++ "_link_not_found",
)
|> ignore;
let xs = Fs.listDirRecursively(tmpdir) |> Lwt_main.run;
expect.list(xs).toContainEqual(Fs.File(filePath ++ "_link"));
expect.list(xs).toContainEqual(
Fs.File(filePath ++ "_link_not_found"),
);
expect.list(xs).toContainEqual(Fs.File(filePath));
expect.list(xs).toContainEqual(Fs.Dir(fileDir));
});
});
test("rmdir", ({expect, _}) => {
let tmpdir = get_tempdir("rmdir");
let fileDir = Filename.concat(tmpdir, "a/b/c/d/e/f/g");
let filePath = Filename.concat(fileDir, "file");
Sys.command("mkdir -p " ++ fileDir) |> ignore;
Sys.command("touch " ++ filePath) |> ignore;
Unix.symlink(filePath, filePath ++ "_link");
Fs.rmdir(tmpdir) |> Lwt_main.run;
let remainingFiles = Fs.listDirRecursively(tmpdir) |> Lwt_main.run;
expect.list(remainingFiles).toBeEmpty();
});
});
Loading…
Cancel
Save