vs_core/service/
install.rs1use crate::{App, CoreError, InstalledVersion};
4
5impl App {
6 pub fn install_plugin_version(
8 &self,
9 plugin_name: &str,
10 version: Option<&str>,
11 progress: Option<&crate::ProgressFn<'_>>,
12 ) -> Result<InstalledVersion, CoreError> {
13 let entry = self.resolve_registry_entry(plugin_name)?;
14 let plugin = self.load_plugin(&entry)?;
15 let available_versions = self.cached_available_versions(plugin_name, &[])?;
16 let selected_version = version
17 .map(str::to_string)
18 .or_else(|| {
19 available_versions
20 .first()
21 .map(|candidate| candidate.version.clone())
22 })
23 .ok_or_else(|| {
24 CoreError::Unsupported(format!(
25 "plugin {plugin_name} does not expose installable versions"
26 ))
27 })?;
28
29 let plan = plugin.install_plan(&selected_version)?;
30 let runtime = self.installer.install(&plan, progress)?;
31
32 if let Err(error) = plugin.post_install(&runtime) {
36 let _ = std::fs::remove_dir_all(&runtime.root_dir);
37 return Err(error.into());
38 }
39
40 Ok(InstalledVersion {
41 plugin: plugin_name.to_string(),
42 version: runtime.version,
43 install_dir: runtime.root_dir,
44 })
45 }
46
47 pub fn project_tool_version(&self, plugin_name: &str) -> Result<Option<String>, CoreError> {
49 Ok(self
50 .resolve_project_tool_version_internal(plugin_name)?
51 .map(|resolved| resolved.version))
52 }
53
54 pub fn configured_tools_for_install(&self) -> Result<Vec<(String, String)>, CoreError> {
56 Ok(self
57 .collect_current_tools()?
58 .into_iter()
59 .map(|tool| (tool.plugin, tool.version))
60 .collect())
61 }
62}