mecha10-cli 0.8.0

Mecha10 CLI tool
Documentation
//! Format command handler
//!
//! Orchestrates code formatting.

use crate::context::CliContext;
use crate::ui::style;
use anyhow::Result;

#[derive(Debug, Clone)]
pub struct FormatArgs {
    pub check: bool,
}

/// Handle format command. Formats all project code.
pub async fn handle_format(ctx: &mut CliContext, args: &FormatArgs) -> Result<()> {
    println!();
    if args.check {
        println!("{}", style::heading("🔍 Code Format Check"));
    } else {
        println!("{}", style::heading("✨ Code Formatting"));
    }
    println!("{}", style::separator(47));
    println!();

    if !ctx.is_project_initialized() {
        return Err(anyhow::anyhow!(
            "Not in a Mecha10 project directory.\n\
             Run 'mecha10 init' to create a new project."
        ));
    }

    let project = ctx.project()?;
    println!("Project: {}", project.root().display());
    println!();

    let mut all_passed = true;

    println!("Formatting Rust code...");
    let rustfmt_result = if args.check {
        std::process::Command::new("cargo")
            .args(["fmt", "--all", "--", "--check"])
            .current_dir(project.root())
            .status()
    } else {
        std::process::Command::new("cargo")
            .args(["fmt", "--all"])
            .current_dir(project.root())
            .status()
    };

    match rustfmt_result {
        Ok(status) if status.success() => {
            if args.check {
                println!("{}", style::success("✅ Rust code is formatted correctly"));
            } else {
                println!("{}", style::success("✅ Rust code formatted"));
            }
        }
        Ok(_) => {
            if args.check {
                println!("{}", style::error("❌ Rust code needs formatting"));
                println!("   Run: mecha10 format");
            } else {
                println!("{}", style::error("❌ Rust formatting failed"));
            }
            all_passed = false;
        }
        Err(e) => {
            println!("{}", style::warn(format!("âš ī¸  Could not run rustfmt: {}", e)));
            println!("   Install with: rustup component add rustfmt");
        }
    }
    println!();

    println!("Formatting TOML files...");
    let toml_files: Vec<_> = walkdir::WalkDir::new(project.root())
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| {
            let path = e.path();
            path.extension().is_some_and(|ext| ext == "toml")
                && !path.to_string_lossy().contains("/target/")
                && !path.to_string_lossy().contains("/node_modules/")
        })
        .map(|e| e.path().to_path_buf())
        .collect();

    if toml_files.is_empty() {
        println!("â„šī¸  No TOML files found, skipping");
    } else {
        let taplo_result = if args.check {
            std::process::Command::new("taplo")
                .arg("format")
                .arg("--check")
                .args(&toml_files)
                .current_dir(project.root())
                .status()
        } else {
            std::process::Command::new("taplo")
                .arg("format")
                .args(&toml_files)
                .current_dir(project.root())
                .status()
        };

        match taplo_result {
            Ok(status) if status.success() => {
                if args.check {
                    println!("{}", style::success("✅ TOML files are formatted correctly"));
                } else {
                    println!("{}", style::success("✅ TOML files formatted"));
                }
            }
            Ok(_) => {
                if args.check {
                    println!("{}", style::error("❌ TOML files need formatting"));
                    println!("   Run: mecha10 format");
                } else {
                    println!("{}", style::error("❌ TOML formatting failed"));
                }
                all_passed = false;
            }
            Err(e) => {
                println!("{}", style::warn(format!("âš ī¸  Could not run taplo: {}", e)));
                println!("   Install with: cargo install taplo-cli --locked");
            }
        }
    }
    println!();

    println!("{}", style::separator(47));
    if all_passed {
        if args.check {
            println!("{}", style::success("✅ All code is formatted correctly!"));
        } else {
            println!("{}", style::success("✅ All code formatted successfully!"));
        }
    } else {
        if args.check {
            println!("{}", style::error("❌ Some code needs formatting"));
            println!();
            println!("Run without --check to format:");
            println!("  mecha10 format");
        } else {
            println!("{}", style::error("❌ Some formatting operations failed"));
        }
        return Err(anyhow::anyhow!("Formatting check failed"));
    }
    println!();

    Ok(())
}