Skip to main content

cargo_mate/cmd/
activate.rs

1use anyhow::Result;
2use std::fs;
3use colored::Colorize;
4use crate::captain::shell_integration::ShellIntegration;
5pub fn handle_activate() -> Result<()> {
6    println!("⚡ Activating Cargo Mate shell integration...");
7    let shell = ShellIntegration::detect_shell()?;
8    let rc_file = ShellIntegration::get_rc_file(&shell)?;
9    if !rc_file.exists() {
10        handle_install()?;
11        println!("❌ No shell configuration file found: {}", rc_file.display());
12        println!("💡 Run 'cm init' first to set up shell integration");
13        return Ok(());
14    }
15    let content = fs::read_to_string(&rc_file)?;
16    if !content.contains("# === Cargo Mate") {
17        println!("❌ Cargo Mate integration not found in {}", rc_file.display());
18        println!("💡 Run 'cm init' first to set up shell integration");
19        return Ok(());
20    }
21    println!("🔄 Sourcing {}", rc_file.display().to_string().cyan());
22    let output = std::process::Command::new(&shell)
23        .arg("-c")
24        .arg(format!("source {} && env", rc_file.display()))
25        .output()?;
26    if output.status.success() {
27        println!();
28        println!("🚢 {}", "You can now use:".yellow());
29        println!("   {} - cargo commands go through cm", "cargo".cyan());
30        println!("   {} - direct cm access", "cm".cyan());
31        println!("   {} - quick alias", "cg".cyan());
32    } else {
33        let error = String::from_utf8_lossy(&output.stderr);
34        println!("❌ Failed to activate integration: {}", error);
35        println!(
36            "💡 You can manually run: {}", format!("source {}", rc_file.display())
37            .green()
38        );
39    }
40    Ok(())
41}
42pub fn handle_install() -> Result<()> {
43    let shell = ShellIntegration::detect_shell()?;
44    let rc_file = ShellIntegration::get_rc_file(&shell)?;
45    if rc_file.exists() {
46        let content = std::fs::read_to_string(&rc_file)?;
47        if content.contains("# === Cargo Mate") {
48            return Ok(());
49        }
50    }
51    let integration_script = format!(
52        r#"
53# === Cargo Mate ===
54# Add ~/.shipwreck/bin to PATH for cargo-mate commands
55if [[ ":$PATH:" != *":$HOME/.shipwreck/bin:"* ]]; then
56    export PATH="$HOME/.shipwreck/bin:$PATH"
57fi
58
59# Function to check if cm command exists (checks multiple locations)
60cm_exists() {{
61    # Try multiple ways to find cm
62    if command -v cm &> /dev/null; then
63        return 0
64    elif [ -x "$HOME/.shipwreck/bin/cm" ]; then
65        return 0
66    elif [ -x "$HOME/.cargo/bin/cm" ]; then
67        return 0
68    elif [ -f "$HOME/.shipwreck/bin/cm" ]; then
69        return 0
70    elif [ -f "$HOME/.cargo/bin/cm" ]; then
71        return 0
72    fi
73    return 1
74}}
75
76# Function to find cm binary path
77find_cm_binary() {{
78    if command -v cm &> /dev/null; then
79        command -v cm
80    elif [ -x "$HOME/.shipwreck/bin/cm" ]; then
81        echo "$HOME/.shipwreck/bin/cm"
82    elif [ -x "$HOME/.cargo/bin/cm" ]; then
83        echo "$HOME/.cargo/bin/cm"
84    else
85        echo "cm"
86    fi
87}}
88
89# Function to intercept cargo commands
90cargo() {{
91    if cm_exists; then
92        # Use the found cm binary
93        CM_BINARY="$(find_cm_binary)"
94        $CM_BINARY exec "$@"
95    else
96        command cargo "$@"
97    fi
98}}
99
100# Alias for quick access
101alias cg='cm'
102
103# Auto-complete for cm (if available)
104if [ -f ~/.shipwreck/completions/cm.bash ]; then
105    source ~/.shipwreck/completions/cm.bash
106fi
107
108# === End Cargo Mate ===
109"#
110    );
111    let mut content = if rc_file.exists() {
112        std::fs::read_to_string(&rc_file)?
113    } else {
114        String::new()
115    };
116    content.push_str(&integration_script);
117    std::fs::write(&rc_file, content)?;
118    Ok(())
119}