vx_cli/commands/
list.rs

1//! List command implementation
2
3use crate::ui::UI;
4use anyhow::Result;
5use vx_paths::{PathManager, PathResolver};
6use vx_plugin::PluginRegistry;
7
8pub async fn handle(
9    registry: &PluginRegistry,
10    tool: Option<&str>,
11    show_status: bool,
12) -> Result<()> {
13    // Create path manager and resolver
14    let path_manager = PathManager::new()
15        .map_err(|e| anyhow::anyhow!("Failed to initialize path manager: {}", e))?;
16    let resolver = PathResolver::new(path_manager);
17
18    match tool {
19        Some(tool_name) => {
20            // List versions for a specific tool
21            list_tool_versions(registry, &resolver, tool_name, show_status).await?;
22        }
23        None => {
24            // List all tools
25            list_all_tools(registry, &resolver, show_status).await?;
26        }
27    }
28    Ok(())
29}
30
31async fn list_tool_versions(
32    registry: &PluginRegistry,
33    resolver: &PathResolver,
34    tool_name: &str,
35    show_status: bool,
36) -> Result<()> {
37    // Check if tool is supported
38    let tool = registry.get_tool(tool_name);
39    if tool.is_none() {
40        UI::error(&format!("Tool '{}' is not supported", tool_name));
41        UI::hint("Use 'vx list' to see all supported tools");
42        return Ok(());
43    }
44
45    UI::info(&format!("šŸ“¦ {}", tool_name));
46
47    // Get installed versions
48    let installed_versions = resolver.manager().list_tool_versions(tool_name)?;
49
50    if installed_versions.is_empty() {
51        UI::hint("  No versions installed");
52        if show_status {
53            UI::hint(&format!(
54                "  Use 'vx install {}' to install this tool",
55                tool_name
56            ));
57        }
58        return Ok(());
59    }
60
61    // Show installed versions
62    for version in &installed_versions {
63        let status_icon = if show_status { "āœ…" } else { "  " };
64        println!("  {} {}", status_icon, version);
65
66        if show_status {
67            let exe_path = resolver.manager().tool_executable_path(tool_name, version);
68            println!("     šŸ“ {}", exe_path.display());
69        }
70    }
71
72    if show_status {
73        UI::success(&format!(
74            "Total: {} version(s) installed",
75            installed_versions.len()
76        ));
77    }
78
79    Ok(())
80}
81
82async fn list_all_tools(
83    registry: &PluginRegistry,
84    resolver: &PathResolver,
85    show_status: bool,
86) -> Result<()> {
87    UI::info("šŸ“¦ Available Tools:");
88
89    // Get all supported tools from registry
90    let supported_tools = registry.list_tools();
91
92    // Get all installed tools
93    let installed_tools = resolver.manager().list_installed_tools()?;
94
95    for tool_name in &supported_tools {
96        let is_installed = installed_tools.contains(tool_name);
97        let status_icon = if is_installed { "āœ…" } else { "āŒ" };
98
99        if let Some(tool) = registry.get_tool(tool_name) {
100            println!("  {} {} - {}", status_icon, tool_name, tool.description());
101
102            if show_status && is_installed {
103                let versions = resolver.manager().list_tool_versions(tool_name)?;
104                if !versions.is_empty() {
105                    println!("     Versions: {}", versions.join(", "));
106                }
107            }
108        }
109    }
110
111    // Show summary
112    if show_status {
113        let total_supported = supported_tools.len();
114        let total_installed = installed_tools.len();
115        UI::info(&format!(
116            "\nšŸ“Š Summary: {}/{} tools installed",
117            total_installed, total_supported
118        ));
119    }
120
121    Ok(())
122}