syncable_cli/analyzer/tool_management/installers/
common.rs1use std::process::Command;
2use crate::error::Result;
3use log::{info, warn, debug};
4
5#[derive(Debug, Clone)]
6pub enum InstallationStrategy {
7 PackageManager(String), DirectDownload { url: String, extract_to: String },
9 Script { command: String, args: Vec<String> },
10 Manual { instructions: String },
11}
12
13pub struct InstallationUtils;
15
16impl InstallationUtils {
17 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 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 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 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}