syncable_cli/analyzer/tool_management/installers/
common.rs

1use std::process::Command;
2use crate::error::Result;
3use log::{info, warn, debug};
4
5#[derive(Debug, Clone)]
6pub enum InstallationStrategy {
7    PackageManager(String), // e.g., "brew", "apt", "cargo"
8    DirectDownload { url: String, extract_to: String },
9    Script { command: String, args: Vec<String> },
10    Manual { instructions: String },
11}
12
13/// Common utilities for tool installation
14pub struct InstallationUtils;
15
16impl InstallationUtils {
17    /// Execute a command and return success status
18    pub fn execute_command(command: &str, args: &[&str]) -> Result<bool> {
19        debug!("Executing command: {} {}", command, args.join(" "));
20        
21        let output = Command::new(command)
22            .args(args)
23            .output()?;
24        
25        if output.status.success() {
26            info!("✅ Command executed successfully: {} {}", command, args.join(" "));
27            Ok(true)
28        } else {
29            let stderr = String::from_utf8_lossy(&output.stderr);
30            warn!("❌ Command failed: {} {} - {}", command, args.join(" "), stderr);
31            Ok(false)
32        }
33    }
34    
35    /// Check if a command is available in PATH
36    pub fn is_command_available(command: &str) -> bool {
37        Command::new(command)
38            .arg("--version")
39            .output()
40            .map(|output| output.status.success())
41            .unwrap_or(false)
42    }
43    
44    /// Get platform-specific installation directory
45    pub fn get_user_bin_dir() -> std::path::PathBuf {
46        if cfg!(windows) {
47            if let Ok(userprofile) = std::env::var("USERPROFILE") {
48                std::path::PathBuf::from(userprofile).join(".local").join("bin")
49            } else {
50                std::path::PathBuf::from(".").join("bin")
51            }
52        } else {
53            if let Ok(home) = std::env::var("HOME") {
54                std::path::PathBuf::from(home).join(".local").join("bin")
55            } else {
56                std::path::PathBuf::from(".").join("bin")
57            }
58        }
59    }
60    
61    /// Create directory if it doesn't exist
62    pub fn ensure_dir_exists(path: &std::path::Path) -> Result<()> {
63        if !path.exists() {
64            std::fs::create_dir_all(path)?;
65            info!("Created directory: {}", path.display());
66        }
67        Ok(())
68    }
69}