syncable_cli/analyzer/tool_management/installers/
python.rs

1use super::common::InstallationUtils;
2use crate::analyzer::tool_management::ToolDetector;
3use crate::error::Result;
4use log::{debug, info, warn};
5use std::collections::HashMap;
6
7/// Install pip-audit for Python vulnerability scanning
8pub fn install_pip_audit(
9    tool_detector: &mut ToolDetector,
10    installed_tools: &mut HashMap<String, bool>,
11) -> Result<()> {
12    if tool_detector.detect_tool("pip-audit").available {
13        return Ok(());
14    }
15
16    info!("🔧 Installing pip-audit for Python vulnerability scanning...");
17
18    // Try different installation methods
19    let install_commands = vec![
20        ("pipx", vec!["install", "pip-audit"]),
21        ("pip3", vec!["install", "--user", "pip-audit"]),
22        ("pip", vec!["install", "--user", "pip-audit"]),
23    ];
24
25    for (cmd, args) in install_commands {
26        debug!("Trying installation command: {} {}", cmd, args.join(" "));
27
28        if InstallationUtils::is_command_available(cmd) {
29            if let Ok(success) = InstallationUtils::execute_command(
30                cmd,
31                &args.iter().map(|s| *s).collect::<Vec<_>>(),
32            ) {
33                if success {
34                    info!("✅ pip-audit installed successfully using {}", cmd);
35                    installed_tools.insert("pip-audit".to_string(), true);
36                    tool_detector.clear_cache();
37                    return Ok(());
38                }
39            }
40        }
41    }
42
43    warn!("📦 Failed to auto-install pip-audit. Please install manually:");
44    warn!("   Option 1: pipx install pip-audit");
45    warn!("   Option 2: pip3 install --user pip-audit");
46
47    Ok(()) // Don't fail, just warn
48}