fix removing symlinks on windows (#9704)

this PR should close #9624

# Description

Fixes the `rm` command assuming that a symlink is a directory and trying
to delete the directory as opposed to unlinking the symlink.

Should probably be tested on linux before merge.

Added tests for deleting symlinks
This commit is contained in:
Alexandra Østermark 2023-07-20 20:16:03 +02:00 committed by GitHub
parent c62cbcd5f8
commit bd9d865912
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View File

@ -393,7 +393,11 @@ fn rm(
trash::delete(&f).map_err(|e: trash::Error| { trash::delete(&f).map_err(|e: trash::Error| {
Error::new(ErrorKind::Other, format!("{e:?}\nTry '--trash' flag")) Error::new(ErrorKind::Other, format!("{e:?}\nTry '--trash' flag"))
}) })
} else if metadata.is_file() || is_socket || is_fifo { } else if metadata.is_file()
|| is_socket
|| is_fifo
|| metadata.file_type().is_symlink()
{
std::fs::remove_file(&f) std::fs::remove_file(&f)
} else { } else {
std::fs::remove_dir_all(&f) std::fs::remove_dir_all(&f)
@ -411,7 +415,11 @@ fn rm(
Err(e) Err(e)
} else if interactive && !confirmed { } else if interactive && !confirmed {
Ok(()) Ok(())
} else if metadata.is_file() || is_socket || is_fifo { } else if metadata.is_file()
|| is_socket
|| is_fifo
|| metadata.file_type().is_symlink()
{
std::fs::remove_file(&f) std::fs::remove_file(&f)
} else { } else {
std::fs::remove_dir_all(&f) std::fs::remove_dir_all(&f)

View File

@ -352,6 +352,29 @@ fn remove_ignores_ansi() {
}); });
} }
#[test]
fn removes_symlink() {
let symlink_target = "symlink_target";
let symlink = "symlink";
Playground::setup("rm_test_symlink", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile(symlink_target)]);
#[cfg(not(windows))]
std::os::unix::fs::symlink(dirs.test().join(symlink_target), dirs.test().join(symlink))
.unwrap();
#[cfg(windows)]
std::os::windows::fs::symlink_file(
dirs.test().join(symlink_target),
dirs.test().join(symlink),
)
.unwrap();
let _ = nu!(cwd: sandbox.cwd(), "rm symlink");
assert!(!dirs.test().join(symlink).exists());
});
}
struct Cleanup<'a> { struct Cleanup<'a> {
dir_to_clean: &'a PathBuf, dir_to_clean: &'a PathBuf,
} }