Skip to main content

vs_core/service/
uninstall.rs

1//! Services for uninstalling previously materialized runtimes.
2
3use std::fs;
4
5use crate::{App, CoreError, UninstallResult, UseScope};
6
7impl App {
8    /// Uninstalls a plugin version from the local cache.
9    ///
10    /// When the uninstalled version is currently active and other versions
11    /// remain, auto-switches to the first remaining version (global scope).
12    /// When no versions remain, removes the entire plugin cache directory.
13    pub fn uninstall_plugin_version(
14        &self,
15        plugin_name: &str,
16        version: &str,
17    ) -> Result<UninstallResult, CoreError> {
18        let was_current = self
19            .current_tool(plugin_name)?
20            .map(|current| current.version == version)
21            .unwrap_or(false);
22
23        let removed = self.installer.uninstall(plugin_name, version)?;
24        if !removed {
25            return Ok(UninstallResult {
26                removed: false,
27                auto_switched: None,
28            });
29        }
30
31        let remaining = self.installer.installed_versions(plugin_name)?;
32
33        if remaining.is_empty() {
34            let plugin_cache = self.home().join("cache").join(plugin_name);
35            if plugin_cache.exists() {
36                let _ = fs::remove_dir_all(plugin_cache);
37            }
38            return Ok(UninstallResult {
39                removed: true,
40                auto_switched: None,
41            });
42        }
43
44        if was_current {
45            let first = &remaining[0];
46            let _ = self.use_tool(plugin_name, first, UseScope::Global, false);
47            return Ok(UninstallResult {
48                removed: true,
49                auto_switched: Some(first.clone()),
50            });
51        }
52
53        Ok(UninstallResult {
54            removed: true,
55            auto_switched: None,
56        })
57    }
58}