1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

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); assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "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(); let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || { blocking_json(is_sync, move || {
#[cfg(not(unix))]
use std::os::windows::prelude::MetadataExt;
let metadata = std::fs::symlink_metadata(&path)?; let metadata = std::fs::symlink_metadata(&path)?;
debug!("op_remove {} {}", path.display(), recursive); debug!("op_remove {} {}", path.display(), recursive);
let file_type = metadata.file_type(); 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)?; std::fs::remove_file(&path)?;
} else if recursive { } else if recursive {
std::fs::remove_dir_all(&path)?; 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 { } else {
std::fs::remove_dir(&path)?; std::fs::remove_dir(&path)?;
} }