terminal_jarvis/installation_arguments.rs
1// src/installation_arguments.rs
2//
3// Tool installation command management and validation
4//
5// This module provides a centralized system for managing installation commands
6// across all supported AI coding tools, with NPM availability validation.
7//
8// Configuration is now loaded from the modular config system for better maintainability
9// and future database integration capabilities.
10
11use crate::tools::tools_command_mapping::{get_install_command, get_update_command};
12use crate::tools::tools_config::get_tool_config_loader;
13use std::collections::HashMap;
14
15/// Installation command structure for compatibility with existing code
16#[derive(Debug, Clone)]
17pub struct InstallCommand {
18 pub command: String,
19 pub args: Vec<String>,
20 pub pipe_to: Option<String>, // For curl-based installations that pipe to bash
21 pub description: String,
22 pub requires_npm: bool,
23 #[allow(dead_code)] // Used for installation privilege management
24 pub requires_sudo: bool,
25}
26
27/// Manages installation commands and dependency validation for AI coding tools
28///
29/// Provides a centralized interface for:
30/// - Checking system dependencies (NPM availability)
31/// - Retrieving installation commands for specific tools
32/// - Validating installation prerequisites
33///
34/// All installation commands are loaded from ai-tools-registry.toml to ensure consistency
35/// and enable easy maintenance without code changes.
36pub struct InstallationManager;
37
38impl InstallationManager {
39 /// Checks if NPM is available on the system
40 ///
41 /// Executes `npm --version` to verify NPM installation and accessibility.
42 /// Used to validate prerequisites before attempting NPM-based tool installations.
43 ///
44 /// # Returns
45 ///
46 /// * `true` - NPM is installed and accessible
47 /// * `false` - NPM is not available or execution failed
48 ///
49 /// # Example
50 ///
51 /// ```rust,ignore
52 /// if InstallationManager::check_npm_available() {
53 /// println!("NPM is available for tool installation");
54 /// } else {
55 /// println!("NPM is required but not found");
56 /// }
57 /// ```
58 pub fn check_npm_available() -> bool {
59 std::process::Command::new("npm")
60 .arg("--version")
61 .output()
62 .map(|output| output.status.success())
63 .unwrap_or(false)
64 }
65
66 /// Checks if curl is available on the system
67 ///
68 /// Executes `curl --version` to verify curl installation and accessibility.
69 /// Used to validate prerequisites before attempting curl-based tool installations.
70 ///
71 /// # Returns
72 ///
73 /// * `true` - curl is installed and accessible
74 /// * `false` - curl is not available or execution failed
75 pub fn check_curl_available() -> bool {
76 std::process::Command::new("curl")
77 .arg("--version")
78 .output()
79 .map(|output| output.status.success())
80 .unwrap_or(false)
81 }
82
83 /// Checks if uv is available on the system
84 ///
85 /// Executes `uv --version` to verify uv installation and accessibility.
86 /// Used to validate prerequisites before attempting uv-based tool installations.
87 ///
88 /// # Returns
89 ///
90 /// * `true` - uv is installed and accessible
91 /// * `false` - uv is not available or execution failed
92 pub fn check_uv_available() -> bool {
93 std::process::Command::new("uv")
94 .arg("--version")
95 .output()
96 .map(|output| output.status.success())
97 .unwrap_or(false)
98 }
99
100 /// Returns a list of all supported tool names
101 ///
102 /// Provides the canonical list of tool names that can be used with
103 /// [`get_install_command`](Self::get_install_command).
104 ///
105 /// # Returns
106 ///
107 /// A vector of tool name strings (e.g., ["claude", "gemini", "qwen"])
108 ///
109 /// # Example
110 ///
111 /// ```rust,ignore
112 /// let tools = InstallationManager::get_tool_names();
113 /// for tool in tools {
114 /// println!("Supported tool: {}", tool);
115 /// }
116 /// ```
117 pub fn get_tool_names() -> Vec<String> {
118 let config_loader = get_tool_config_loader();
119 config_loader.get_tool_names()
120 }
121
122 /// Retrieves installation command for a specific tool
123 ///
124 /// # Arguments
125 ///
126 /// * `tool` - The name of the tool (e.g., "claude", "gemini")
127 ///
128 /// # Returns
129 ///
130 /// * `Some(InstallCommand)` - Installation command metadata if tool is supported
131 /// * `None` - If the tool name is not recognized
132 ///
133 /// # Example
134 ///
135 /// ```rust,ignore
136 /// if let Some(cmd) = InstallationManager::get_install_command("claude") {
137 /// println!("Install command: {} {}", cmd.command, cmd.args.join(" "));
138 /// } else {
139 /// println!("Tool not found");
140 /// }
141 /// ```
142 pub fn get_install_command(tool: &str) -> Option<InstallCommand> {
143 get_install_command(tool).map(|cmd| InstallCommand {
144 command: cmd.command,
145 args: cmd.args,
146 pipe_to: cmd.pipe_to,
147 description: cmd.description,
148 requires_npm: cmd.requires_npm,
149 requires_sudo: cmd.requires_sudo,
150 })
151 }
152
153 /// Retrieves update command for a specific tool
154 ///
155 /// # Arguments
156 ///
157 /// * `tool` - The name of the tool (e.g., "claude", "gemini")
158 ///
159 /// # Returns
160 ///
161 /// * `Some(InstallCommand)` - Update command metadata if tool is supported
162 /// * `None` - If the tool name is not recognized
163 ///
164 /// # Example
165 ///
166 /// ```rust,ignore
167 /// if let Some(cmd) = InstallationManager::get_update_command("claude") {
168 /// println!("Update command: {} {}", cmd.command, cmd.args.join(" "));
169 /// } else {
170 /// println!("Tool not found");
171 /// }
172 /// ```
173 #[allow(dead_code)] // Used by update functionality
174 pub fn get_update_command(tool: &str) -> Option<InstallCommand> {
175 get_update_command(tool).map(|cmd| InstallCommand {
176 command: cmd.command,
177 args: cmd.args,
178 pipe_to: cmd.pipe_to,
179 description: cmd.description,
180 requires_npm: cmd.requires_npm,
181 requires_sudo: cmd.requires_sudo,
182 })
183 }
184
185 /// Returns all available installation commands
186 ///
187 /// Provides the complete mapping of tool names to their installation commands.
188 /// This is the authoritative source for all supported tools and their metadata.
189 ///
190 /// # Returns
191 ///
192 /// A HashMap mapping tool names to their InstallCommand structures
193 ///
194 /// # Note
195 ///
196 /// This method loads from the modular TOML configuration files in `config/tools/` on each call.
197 /// For single-tool lookups, prefer [`get_install_command`](Self::get_install_command).
198 pub fn get_install_commands() -> HashMap<String, InstallCommand> {
199 let config_loader = get_tool_config_loader();
200 let tool_names = config_loader.get_tool_names();
201 let mut commands = HashMap::new();
202
203 for tool in tool_names {
204 if let Some(cmd) = get_install_command(&tool) {
205 commands.insert(
206 tool,
207 InstallCommand {
208 command: cmd.command,
209 args: cmd.args,
210 pipe_to: cmd.pipe_to,
211 description: cmd.description,
212 requires_npm: cmd.requires_npm,
213 requires_sudo: cmd.requires_sudo,
214 },
215 );
216 }
217 }
218
219 commands
220 }
221}