vx_cli/commands/
install.rs1use crate::ui::UI;
4use vx_core::{PluginRegistry, Result, VxError};
5
6pub async fn handle(
7 registry: &PluginRegistry,
8 tool_name: &str,
9 version: Option<&str>,
10 force: bool,
11) -> Result<()> {
12 let tool = registry
14 .get_tool(tool_name)
15 .ok_or_else(|| VxError::ToolNotFound {
16 tool_name: tool_name.to_string(),
17 })?;
18
19 let target_version = if let Some(v) = version {
21 v.to_string()
22 } else {
23 UI::info(&format!("Fetching latest version for {}...", tool_name));
25 let versions = tool.fetch_versions(false).await?;
26 if versions.is_empty() {
27 return Err(VxError::VersionNotFound {
28 tool_name: tool_name.to_string(),
29 version: "latest".to_string(),
30 });
31 }
32 versions[0].version.clone()
33 };
34
35 UI::info(&format!("Installing {} {}...", tool_name, target_version));
36
37 if !force && tool.is_version_installed(&target_version).await? {
39 UI::success(&format!(
40 "{} {} is already installed",
41 tool_name, target_version
42 ));
43 UI::hint("Use --force to reinstall");
44 return Ok(());
45 }
46
47 match tool.install_version(&target_version, force).await {
49 Ok(()) => {
50 UI::success(&format!(
51 "Successfully installed {} {}",
52 tool_name, target_version
53 ));
54
55 let install_dir = tool.get_version_install_dir(&target_version);
57 UI::detail(&format!("Installed to: {}", install_dir.display()));
58
59 UI::hint(&format!(
61 "Use 'vx {} --version' to verify installation",
62 tool_name
63 ));
64 }
65 Err(e) => {
66 UI::error(&format!(
67 "Failed to install {} {}: {}",
68 tool_name, target_version, e
69 ));
70 return Err(e);
71 }
72 }
73
74 Ok(())
75}