Add uv_fs::remove_symlink

This commit is contained in:
Tomasz (Tom) Kramkowski
2026-06-18 00:20:46 +01:00
parent ac8a4615da
commit d7b3d315b2
2 changed files with 42 additions and 7 deletions
+41 -1
View File
@@ -260,8 +260,24 @@ pub fn create_symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> std::io::
fs_err::os::unix::fs::symlink(src.as_ref(), dst.as_ref())
}
/// Remove a symbolic link at `path` without following its target.
pub fn remove_symlink(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref();
#[cfg(windows)]
{
use std::os::windows::fs::FileTypeExt;
if fs_err::symlink_metadata(path)?.file_type().is_symlink_dir() {
return fs_err::remove_dir(path);
}
}
fs_err::remove_file(path)
}
#[cfg(all(test, windows))]
mod tests {
mod windows_tests {
use std::os::windows::ffi::OsStrExt;
use super::*;
@@ -889,3 +905,27 @@ pub fn remove_virtualenv(location: &Path) -> io::Result<()> {
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn remove_symlink_removes_directory_link_without_removing_target() -> std::io::Result<()> {
let tempdir = tempfile::tempdir()?;
let target = tempdir.path().join("target");
fs_err::create_dir(&target)?;
fs_err::write(target.join("file"), "content")?;
let link = tempdir.path().join("link");
create_symlink(&target, &link)?;
remove_symlink(&link)?;
assert!(matches!(
fs_err::symlink_metadata(&link),
Err(err) if err.kind() == std::io::ErrorKind::NotFound
));
assert_eq!(fs_err::read_to_string(target.join("file"))?, "content");
Ok(())
}
}
+1 -6
View File
@@ -249,12 +249,7 @@ async fn do_uninstall(
PythonMinorVersionLink::from_installation(installation)
{
if minor_version_link.exists() {
let result = if cfg!(windows) {
fs_err::remove_dir(minor_version_link.symlink_directory.as_path())
} else {
fs_err::remove_file(minor_version_link.symlink_directory.as_path())
};
if result.is_err() {
if uv_fs::remove_symlink(&minor_version_link.symlink_directory).is_err() {
return Err(anyhow::anyhow!(
"Failed to remove symlink directory {}",
minor_version_link.symlink_directory.display()