diff --git a/Cargo.lock b/Cargo.lock index 531d42b..bfdfd1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,7 +227,6 @@ dependencies = [ "assert_cmd", "clap", "directories", - "fs_extra", "ignore", "serde", "serde_json", @@ -305,12 +304,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "getrandom" version = "0.2.16" diff --git a/Cargo.toml b/Cargo.toml index 81adf91..0ceb721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ description = "A tool that simplifies installation and running C# language serve anyhow = "1" clap = { version = "4", features = ["derive"] } directories = "6" -fs_extra = "1" ignore = "0.4" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src/server.rs b/src/server.rs index f43e01e..3c77e83 100644 --- a/src/server.rs +++ b/src/server.rs @@ -82,11 +82,11 @@ async fn ensure_server_is_installed( return Ok(get_server_path(&server_version_dir, rid)); } - fs_extra::dir::create_all(server_root_dir, remove_old_server_versions)?; - fs_extra::dir::create_all(&server_version_dir, true)?; + create_all(server_root_dir, remove_old_server_versions)?; + create_all(&server_version_dir, true)?; let temp_build_root = temp_dir().join("csharp-language-server"); - fs_extra::dir::create(&temp_build_root, true)?; + create(&temp_build_root, true)?; create_csharp_project(&temp_build_root)?; @@ -115,12 +115,8 @@ async fn ensure_server_is_installed( .join("content") .join("LanguageServer"); - let copy_options = fs_extra::dir::CopyOptions::default() - .overwrite(true) - .content_only(true); - - fs_extra::dir::move_dir(&temp_build_dir, &server_version_dir, ©_options)?; - fs_extra::dir::remove(temp_build_dir)?; + move_dir(&temp_build_dir, &server_version_dir)?; + remove(temp_build_root)?; Ok(get_server_path(&server_version_dir, rid)) } @@ -185,3 +181,52 @@ const fn current_rid() -> &'static str { "neutral" } + +fn create_all>(path: P, erase: bool) -> Result<()> { + if erase && path.as_ref().exists() { + remove(&path)?; + } + Ok(fs::create_dir_all(&path)?) +} + +fn remove>(path: P) -> Result<()> { + if path.as_ref().exists() { + Ok(fs::remove_dir_all(path)?) + } else { + Ok(()) + } +} + +fn create>(path: P, erase: bool) -> Result<()> { + if erase && path.as_ref().exists() { + remove(&path)?; + } + Ok(fs::create_dir(&path)?) +} + +fn move_dir(src: &Path, dst: &Path) -> std::io::Result<()> { + match fs::rename(src, dst) { + Ok(()) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::CrossesDevices => { + copy_tree(src, dst)?; + fs::remove_dir_all(src) + } + Err(e) => Err(e), + } +} + +fn copy_tree(src: &Path, dst: &Path) -> std::io::Result<()> { + fs::create_dir_all(dst)?; + for entry in fs::read_dir(src)? { + let entry = entry?; + let from = entry.path(); + let to = dst.join(entry.file_name()); + + if from.is_dir() { + copy_tree(&from, &to)?; + } else { + fs::copy(&from, &to)?; + } + } + Ok(()) +}