Windows: implement symlink (#9508)

Since Windows has a distinction between symlinks for directories and
symlinks for files, the implementation is adapted to this distinction.

Release Notes:

- N/A
This commit is contained in:
白山風露 2024-03-19 06:27:39 +09:00 committed by GitHub
parent cd9b865e0a
commit c0f8581b29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -120,11 +120,15 @@ impl Fs for RealFs {
} }
async fn create_symlink(&self, path: &Path, target: PathBuf) -> Result<()> { async fn create_symlink(&self, path: &Path, target: PathBuf) -> Result<()> {
#[cfg(target_family = "unix")] #[cfg(unix)]
smol::fs::unix::symlink(target, path).await?; smol::fs::unix::symlink(target, path).await?;
#[cfg(target_family = "windows")] #[cfg(windows)]
Err(anyhow!("not supported yet on windows"))?; if smol::fs::metadata(&target).await?.is_dir() {
smol::fs::windows::symlink_dir(target, path).await?
} else {
smol::fs::windows::symlink_file(target, path).await?
}
Ok(()) Ok(())
} }
@ -202,6 +206,21 @@ impl Fs for RealFs {
} }
async fn remove_file(&self, path: &Path, options: RemoveOptions) -> Result<()> { async fn remove_file(&self, path: &Path, options: RemoveOptions) -> Result<()> {
#[cfg(windows)]
if let Ok(Some(metadata)) = self.metadata(path).await {
if metadata.is_symlink && metadata.is_dir {
self.remove_dir(
path,
RemoveOptions {
recursive: false,
ignore_if_not_exists: true,
},
)
.await?;
return Ok(());
}
}
match smol::fs::remove_file(path).await { match smol::fs::remove_file(path).await {
Ok(()) => Ok(()), Ok(()) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound && options.ignore_if_not_exists => { Err(err) if err.kind() == io::ErrorKind::NotFound && options.ignore_if_not_exists => {