Make Deno.remove() work with directory symlinks on windows (#5488)

This commit is contained in:
Ali Hasani 2020-05-18 17:20:44 +04:30 committed by GitHub
parent 2a038eafcd
commit c3ec16535f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 1 deletions

View file

@ -479,3 +479,48 @@ unitTest({ perms: { write: false } }, async function removeAllPerm(): Promise<
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
if (Deno.build.os === "windows") {
unitTest(
{ perms: { run: true, write: true, read: true } },
async function removeFileSymlink(): Promise<void> {
const symlink = Deno.run({
cmd: ["cmd", "/c", "mklink", "file_link", "bar"],
stdout: "null",
});
assert(await symlink.status());
symlink.close();
await Deno.remove("file_link");
let err;
try {
await Deno.lstat("file_link");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { run: true, write: true, read: true } },
async function removeDirSymlink(): Promise<void> {
const symlink = Deno.run({
cmd: ["cmd", "/c", "mklink", "/d", "dir_link", "bar"],
stdout: "null",
});
assert(await symlink.status());
symlink.close();
await Deno.remove("dir_link");
let err;
try {
await Deno.lstat("dir_link");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
}

View file

@ -394,13 +394,29 @@ fn op_remove(
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
#[cfg(not(unix))]
use std::os::windows::prelude::MetadataExt;
let metadata = std::fs::symlink_metadata(&path)?;
debug!("op_remove {} {}", path.display(), recursive);
let file_type = metadata.file_type();
if file_type.is_file() || file_type.is_symlink() {
if file_type.is_file() {
std::fs::remove_file(&path)?;
} else if recursive {
std::fs::remove_dir_all(&path)?;
} else if file_type.is_symlink() {
#[cfg(unix)]
std::fs::remove_file(&path)?;
#[cfg(not(unix))]
{
use winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY;
if metadata.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0 {
std::fs::remove_dir(&path)?;
} else {
std::fs::remove_file(&path)?;
}
}
} else {
std::fs::remove_dir(&path)?;
}