cargo-mate 1.8.0

Rust development companion that enhances cargo with intelligent workflows, state management, performance optimization, and comprehensive project monitoring.
Documentation
use anyhow::Result;
use chrono;
use clap::Parser;
use colored::*;
use serde::{Deserialize, Serialize};
use serde_json;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use reqwest;
use progress::{BuildProgressBar, BuildTracker, BuildRecord};
use std::sync::atomic::Ordering;
use std::time::Instant;
use std::collections::HashMap;
use std::process::Output;
use cargo_mate::cmd::smune::{Args, Commands, JourneyAction};
use cargo_mate::cmd::{
    init, help, log, map, mutiny, config, version, view, test, optimize, checklist,
    activate, journey, idea, tool, scrub, sweep, anchor, captain, tide, ddr, liberate, tree, stub, bin,
};
use cargo_mate::probe;
use cargo_mate::scat;
use cargo_mate::cmd::smune::DockDockRustCommands;
use cargo_mate::cmd::ddr::DdrAction;
use cargo_mate::captain::{
    config::ConfigManager, wtf, license::LicenseManager,
    shell_integration::ShellIntegration, captain_status,
};
use cargo_mate::history;
use cargo_mate::strip;
use cargo_mate::admin_msg;
use cargo_mate::sweeping;
use cargo_mate::journey::JourneyPlayer;
use cargo_mate::display;
use cargo_mate::cmd::init::where_the_cm;
mod tools;
mod command_factory;
mod progress;
mod utils;
#[tokio::main]
async fn main() -> Result<()> {
    if let Err(e) = run().await {
        eprintln!("❌ Error: {}", e);
        cargo_mate::captain::wtf::display_api_failure_art();
        std::process::exit(1);
    }
    Ok(())
}
async fn run() -> Result<()> {
    init::ensure_initialized();
    where_the_cm();
    let args = Args::parse();
    if !matches!(args.command, Some(Commands::Register { .. }) | None) {
        let should_check = match &args.command {
            Some(cmd) => !matches!(cmd, Commands::Activate | Commands::Install),
            None => true,
        };
        if should_check {
            tokio::spawn(async move {
                let _ = admin_msg::check_and_display_message().await;
            });
        }
    }
    if let Some(ref command) = args.command {
        match command {
            Commands::Register { .. } => {}
            Commands::Exec { .. } => {
                // Skip license check entirely for exec - it's called very frequently
                // and blocking would cause significant delays (15-30s on Mac)
            }
            _ => {
                let license_manager = LicenseManager::new()?;
                match command {
                    Commands::Exec { .. } => {
                        // Already handled above, should never reach here
                    }
                    Commands::Init => {
                        license_manager.enforce_license("init")?;
                    }
                    Commands::Journey { .. } => {
                        license_manager.enforce_license("journey")?;
                    }
                    Commands::Anchor { .. } => {
                        license_manager.enforce_license("anchor")?;
                    }
                    Commands::Log { .. } => {
                        license_manager.enforce_license("log")?;
                    }
                    Commands::Tide { .. } => {
                        license_manager.enforce_license("tide")?;
                    }
                    Commands::Map { .. } => {
                        license_manager.enforce_license("map")?;
                    }
                    Commands::Mutiny { .. } => {
                        license_manager.enforce_license("mutiny")?;
                    }
                    Commands::Config { .. } => {
                        license_manager.enforce_license("config")?;
                    }
                    Commands::Version { .. } => {
                        license_manager.enforce_license("version")?;
                    }
                    Commands::View { .. } => {
                        tokio::task::spawn_blocking(|| -> anyhow::Result<()> {
                            let lm = LicenseManager::new()?;
                            lm.enforce_license("view")
                        })
                        .await??;
                    }
                    Commands::Test => {
                        license_manager.enforce_license("test")?;
                    }
                    Commands::Probe { .. } => {
                        license_manager.enforce_license("probe")?;
                    }
                    Commands::Optimize { .. } => {
                        license_manager.enforce_license("optimize")?;
                    }
                    Commands::Checklist { .. } => {
                        license_manager.enforce_license("checklist")?;
                    }
                    Commands::History { .. } => {
                        license_manager.enforce_license("history")?;
                    }
                    Commands::Scrub { .. } => {
                        license_manager.enforce_license("scrub")?;
                    }
                    Commands::Sweep { .. } => {}
                    Commands::Install => {
                        license_manager.enforce_license("install")?;
                    }
                    Commands::Activate => {
                        license_manager.enforce_license("activate")?;
                    }
                    Commands::Idea { .. } => {
                        license_manager.enforce_license("idea")?;
                    }
                    Commands::Wtf { .. } => {
                        license_manager.enforce_license("wtf")?;
                    }
                    Commands::User => {
                        license_manager.enforce_license("user")?;
                    }
                    Commands::Debug => {
                        license_manager.enforce_license("debug")?;
                    }
                    Commands::Strip(_) => {}
                    Commands::Scat { .. } => {
                        license_manager.enforce_license("scat")?;
                    }
                    Commands::Tool { .. } => {
                        license_manager.enforce_license("tool")?;
                    }
                    Commands::Ddr { .. } => {
                        license_manager.enforce_license("ddr")?;
                    }
                    Commands::Deps { .. } => {
                        tokio::task::spawn_blocking(|| -> anyhow::Result<()> {
                            let lm = LicenseManager::new()?;
                            lm.enforce_license("deps")
                        })
                        .await??;
                    }
                    Commands::Liberate { .. } => {
                        license_manager.enforce_license("liberate")?;
                    }
                    Commands::Tree { .. } => {
                        license_manager.enforce_license("tree")?;
                    }
                    Commands::Stub { .. } => {
                        license_manager.enforce_license("stub")?;
                    }
                    Commands::Bin { .. } => {
                        license_manager.enforce_license("bin")?;
                    }
                    Commands::Register { .. } => {}
                }
            }
        }
    }
    match args.command {
        Some(command) => execute_command(command).await,
        None => handle_default_command(),
    }
}
fn update_path_for_captain() {
    let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
    let current_path = std::env::var("PATH").unwrap_or_default();
    let new_path = format!("{}/.shipwreck/bin:{}", home, current_path);
    std::env::set_var("PATH", new_path);
}
fn should_check_admin_msg(args: &Args) -> bool {
    match args.command {
        Some(Commands::Register { .. })
        | Some(Commands::Activate)
        | Some(Commands::Install) => false,
        _ => true,
    }
}
fn requires_license_check(args: &Args) -> bool {
    match args.command {
        Some(Commands::Wtf { .. }) | Some(Commands::Exec { .. }) => false,
        _ => true,
    }
}
fn is_cargo_command(args: &Args) -> bool {
    matches!(args.command, Some(Commands::Exec { .. })) || args.command.is_none()
}
fn get_command_name(args: &Args) -> String {
    match &args.command {
        Some(cmd) => cmd.name().to_string(),
        None => "build".to_string(),
    }
}
fn format_command(args: &Args) -> String {
    match &args.command {
        Some(Commands::Exec { cargo_args }) => format!("cargo {}", cargo_args.join(" ")),
        Some(cmd) => format!("cm {}", cmd.name()),
        None => "cargo build".to_string(),
    }
}
async fn execute_command(command: Commands) -> Result<()> {
    match command {
        Commands::Init => init::handle_init(),
        Commands::Journey { action } => journey::handle_journey(action),
        Commands::Anchor { action } => anchor::handle_anchor(action),
        Commands::Log { action } => log::handle_log(action),
        Commands::Tide { action } => tide::handle_tide(action),
        Commands::Map { action } => map::handle_map_internal(action),
        Commands::Mutiny { action } => mutiny::handle_mutiny_internal(action),
        Commands::Config { action } => config::handle_config(action),
        Commands::Version { action } => version::handle_version(action),
        Commands::View { action } => view::handle_view(action),
        Commands::Test => test::handle_test(),
        Commands::Probe { action } => probe::handle_probe(action),
        Commands::Optimize { action } => optimize::handle_optimize(action),
        Commands::Checklist { action } => checklist::handle_checklist_internal(action),
        Commands::History { kind, limit } => {
            let args = vec![kind, limit.to_string()];
            history::show_history(&args);
            Ok(())
        }
        Commands::Ddr { action } => match action {
            DockDockRustCommands::DockDockRust { image, target, jobs, config, .. } => {
                let ddr_action = DdrAction::Build {
                    image: Some(image),
                    target,
                    jobs,
                    config,
                    use_config: false,
                };
                ddr::handle_ddr(Some(ddr_action)).await
            }
        },
        Commands::Scrub { action } => scrub::handle_scrub(action),
        Commands::Sweep { action } => sweep::handle_sweep(action),
        Commands::Install => activate::handle_install(),
        Commands::Activate => activate::handle_activate(),
        Commands::Register { license_key, status, remaining } => {
            let mut config = ConfigManager::new()?;
            if let Some(key) = license_key {
                config.set("license.key", &key, true)?;
            }
            if status {
                config.set("license.status", "true", true)?;
            }
            if remaining {
                config.set("license.remaining", "true", true)?;
            }
            Ok(())
        }
        Commands::Idea { idea } => idea::handle_idea(&idea),
        Commands::Wtf { action } => wtf::handle_wtf_action(action),
        Commands::User => {
            println!("👤 User management requires captain binary");
            Ok(())
        }
        Commands::Debug => {
            println!("🔍 Debug mode enabled");
            Ok(())
        }
        Commands::Exec { cargo_args } => {
            // No license check for exec - it's called too frequently and would cause delays
            // License is checked for other cm commands, but not for cargo passthrough
            let args_refs: Vec<&str> = cargo_args.iter().map(|s| s.as_str()).collect();
            display::run_cargo_with_display(&args_refs);
            Ok(())
        }
        Commands::Strip(args) => strip::handle_strip_command(args),
        Commands::Scat { command } => scat::handle_scat_command(command),
        Commands::Tool { action } => tool::handle_tool(action),
        Commands::Deps { path, json } => {
            tokio::task::spawn_blocking(|| -> anyhow::Result<()> {
                let lm = LicenseManager::new()?;
                lm.enforce_license("deps")
            })
            .await??;
            cargo_mate::cmd::deps::handle_deps_async(path, json).await
        }
        Commands::Liberate { target, out } => {
            tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
                let lm = LicenseManager::new()?;
                lm.enforce_license("liberate")?;
                liberate::handle_liberate(target, out)
            })
            .await??;
            Ok(())
        }
        Commands::Tree { action, target, out, no_folders, no_files, folder_size, file_size, line_count, dates, style, yolo } => {
            tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
                let lm = LicenseManager::new()?;
                lm.enforce_license("tree")?;
                tree::handle_tree(action, target, out, no_folders, no_files, folder_size, file_size, line_count, dates, style, yolo)
            })
            .await??;
            Ok(())
        }
        Commands::Stub { action, target, out, ext, custom, find, skip } => {
            tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
                let lm = LicenseManager::new()?;
                lm.enforce_license("stub")?;
                stub::handle_stub(action, target, out, ext, custom, find, skip)
            })
            .await??;
            Ok(())
        }
        Commands::Bin { action, path, name, out, timeout_seconds, max_depth } => {
            tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
                let lm = LicenseManager::new()?;
                lm.enforce_license("bin")?;
                bin::handle_bin(action, path, name, out, timeout_seconds, max_depth)
            })
            .await??;
            Ok(())
        }
    }
}
fn handle_default_command() -> Result<()> {
    let config = ConfigManager::new()?;
    let license_status = config
        .get("license.status")
        .unwrap_or_else(|| "inactive".to_string());
    if license_status == "active" {
        let journey_action = JourneyAction::Play {
            name: "default".to_string(),
            dry_run: false,
        };
        return journey::handle_journey(journey_action);
    } else {
        match license_status.as_str() {
            "inactive" => {
                help::show_help()?;
                return Ok(());
            }
            _ => {
                help::show_help()?;
                return Ok(());
            }
        }
    }
    activate::handle_install();
    activate::handle_activate();
    Ok(())
}