Support file or directory removal for Windows symlinks (#15543)

## Summary

Similar to https://github.com/rust-lang/cargo/pull/13910.

I think this should close https://github.com/astral-sh/uv/issues/15541
since we're indiscriminately calling `remove_dir` on that dangling
symlink.
This commit is contained in:
Charlie Marsh 2025-08-27 07:43:03 -04:00 committed by GitHub
parent db4dfb4cf9
commit 9108b04642
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 27 additions and 5 deletions

View File

@ -64,9 +64,22 @@ impl Removal {
// Remove the file.
self.total_bytes += metadata.len();
if cfg!(windows) && metadata.is_symlink() {
// Remove the junction.
remove_dir(path)?;
if metadata.is_symlink() {
#[cfg(windows)]
{
use std::os::windows::fs::FileTypeExt;
if metadata.file_type().is_symlink_dir() {
remove_dir(path)?;
} else {
remove_file(path)?;
}
}
#[cfg(not(windows))]
{
remove_file(path)?;
}
} else {
remove_file(path)?;
}
@ -94,8 +107,17 @@ impl Removal {
}
let entry = entry?;
if cfg!(windows) && entry.file_type().is_symlink() {
// Remove the junction.
if entry.file_type().is_symlink() && {
#[cfg(windows)]
{
use std::os::windows::fs::FileTypeExt;
entry.file_type().is_symlink_dir()
}
#[cfg(not(windows))]
{
false
}
} {
self.num_files += 1;
remove_dir(entry.path())?;
} else if entry.file_type().is_dir() {