summaryrefslogtreecommitdiff
path: root/cli/tools/installer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/installer.rs')
-rw-r--r--cli/tools/installer.rs83
1 files changed, 83 insertions, 0 deletions
diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs
index 4d4709e28..18d2d20e7 100644
--- a/cli/tools/installer.rs
+++ b/cli/tools/installer.rs
@@ -139,6 +139,57 @@ pub fn infer_name_from_url(url: &Url) -> Option<String> {
Some(stem)
}
+pub fn uninstall(name: String, root: Option<PathBuf>) -> Result<(), AnyError> {
+ let root = if let Some(root) = root {
+ canonicalize_path(&root)?
+ } else {
+ get_installer_root()?
+ };
+ let installation_dir = root.join("bin");
+
+ // ensure directory exists
+ if let Ok(metadata) = fs::metadata(&installation_dir) {
+ if !metadata.is_dir() {
+ return Err(generic_error("Installation path is not a directory"));
+ }
+ }
+
+ let mut file_path = installation_dir.join(&name);
+
+ let mut removed = false;
+
+ if file_path.exists() {
+ fs::remove_file(&file_path)?;
+ println!("deleted {}", file_path.to_string_lossy());
+ removed = true
+ };
+
+ if cfg!(windows) {
+ file_path = file_path.with_extension("cmd");
+ if file_path.exists() {
+ fs::remove_file(&file_path)?;
+ println!("deleted {}", file_path.to_string_lossy());
+ removed = true
+ }
+ }
+
+ if !removed {
+ return Err(generic_error(format!("No installation found for {}", name)));
+ }
+
+ // There might be some extra files to delete
+ for ext in ["tsconfig.json", "lock.json"] {
+ file_path = file_path.with_extension(ext);
+ if file_path.exists() {
+ fs::remove_file(&file_path)?;
+ println!("deleted {}", file_path.to_string_lossy());
+ }
+ }
+
+ println!("✅ Successfully uninstalled {}", name);
+ Ok(())
+}
+
pub fn install(
flags: Flags,
module_url: &str,
@@ -926,4 +977,36 @@ mod tests {
let content = fs::read_to_string(file_path).unwrap();
assert!(content.contains(&expected_string));
}
+
+ #[test]
+ fn uninstall_basic() {
+ let temp_dir = TempDir::new().expect("tempdir fail");
+ let bin_dir = temp_dir.path().join("bin");
+ std::fs::create_dir(&bin_dir).unwrap();
+
+ let mut file_path = bin_dir.join("echo_test");
+ File::create(&file_path).unwrap();
+ if cfg!(windows) {
+ file_path = file_path.with_extension("cmd");
+ File::create(&file_path).unwrap();
+ }
+
+ // create extra files
+ file_path = file_path.with_extension("tsconfig.json");
+ File::create(&file_path).unwrap();
+ file_path = file_path.with_extension("lock.json");
+ File::create(&file_path).unwrap();
+
+ uninstall("echo_test".to_string(), Some(temp_dir.path().to_path_buf()))
+ .expect("Uninstall failed");
+
+ assert!(!file_path.exists());
+ assert!(!file_path.with_extension("tsconfig.json").exists());
+ assert!(!file_path.with_extension("lock.json").exists());
+
+ if cfg!(windows) {
+ file_path = file_path.with_extension("cmd");
+ assert!(!file_path.exists());
+ }
+ }
}