From c0f8581b296e4f4f72bb4cf2d3a413d799a94095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=B1=B1=E9=A2=A8=E9=9C=B2?= Date: Tue, 19 Mar 2024 06:27:39 +0900 Subject: [PATCH] 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 --- crates/fs/src/fs.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 1a7638c640..62bf24864d 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -120,11 +120,15 @@ impl Fs for RealFs { } async fn create_symlink(&self, path: &Path, target: PathBuf) -> Result<()> { - #[cfg(target_family = "unix")] + #[cfg(unix)] smol::fs::unix::symlink(target, path).await?; - #[cfg(target_family = "windows")] - Err(anyhow!("not supported yet on windows"))?; + #[cfg(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(()) } @@ -202,6 +206,21 @@ impl Fs for RealFs { } 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 { Ok(()) => Ok(()), Err(err) if err.kind() == io::ErrorKind::NotFound && options.ignore_if_not_exists => {