vs_core/service/
install.rs1use crate::{App, CoreError, InstalledVersion};
2
3impl App {
4 pub fn install_plugin_version(
6 &self,
7 plugin_name: &str,
8 version: Option<&str>,
9 ) -> Result<InstalledVersion, CoreError> {
10 let entry = self.resolve_registry_entry(plugin_name)?;
11 let plugin = self.load_plugin(&entry)?;
12 let available_versions = plugin.available_versions(&[])?;
13 let selected_version = version
14 .map(str::to_string)
15 .or_else(|| {
16 available_versions
17 .first()
18 .map(|candidate| candidate.version.clone())
19 })
20 .ok_or_else(|| {
21 CoreError::Unsupported(format!(
22 "plugin {plugin_name} does not expose installable versions"
23 ))
24 })?;
25
26 let plan = plugin.install_plan(&selected_version)?;
27 let runtime = self.installer.install(&plan)?;
28 plugin.post_install(&runtime)?;
29 Ok(InstalledVersion {
30 plugin: plugin_name.to_string(),
31 version: runtime.version,
32 install_dir: runtime.root_dir,
33 })
34 }
35
36 pub fn project_tool_version(&self, plugin_name: &str) -> Result<Option<String>, CoreError> {
38 Ok(vs_config::find_project_file(&self.cwd)
39 .map(|path| vs_config::read_tool_versions(&path))
40 .transpose()?
41 .and_then(|tools| tools.tools.get(plugin_name).cloned()))
42 }
43
44 pub fn configured_tools_for_install(&self) -> Result<Vec<(String, String)>, CoreError> {
46 Ok(self
47 .collect_current_tools()?
48 .into_iter()
49 .map(|tool| (tool.plugin, tool.version))
50 .collect())
51 }
52}