mecha10-cli 0.7.0

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

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

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

/// Handle format command
///
/// Formats all project code.
///
/// # Arguments
///
/// * `ctx` - CLI execution context
/// * `args` - Format command arguments
pub async fn handle_format(ctx: &mut CliContext, args: &FormatArgs) -> Result<()> {
    println!();
    if args.check {
        println!("🔍 Code Format Check");
    } else {
        println!("✨ Code Formatting");
    }
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    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!("✅ Rust code is formatted correctly");
            } else {
                println!("✅ Rust code formatted");
            }
        }
        Ok(_) => {
            if args.check {
                println!("❌ Rust code needs formatting");
                println!("   Run: mecha10 format");
            } else {
                println!("❌ Rust formatting failed");
            }
            all_passed = false;
        }
        Err(e) => {
            println!("âš ī¸  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!("✅ TOML files are formatted correctly");
                } else {
                    println!("✅ TOML files formatted");
                }
            }
            Ok(_) => {
                if args.check {
                    println!("❌ TOML files need formatting");
                    println!("   Run: mecha10 format");
                } else {
                    println!("❌ TOML formatting failed");
                }
                all_passed = false;
            }
            Err(e) => {
                println!("âš ī¸  Could not run taplo: {}", e);
                println!("   Install with: cargo install taplo-cli --locked");
            }
        }
    }
    println!();

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

    Ok(())
}