use crate::context::CliContext;
use anyhow::Result;
#[derive(Debug, Clone)]
pub struct LintArgs {
pub fix: bool,
}
pub async fn handle_lint(ctx: &mut CliContext, args: &LintArgs) -> Result<()> {
println!();
println!("🔍 Code Linting");
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!("Running Rust linting (clippy)...");
let clippy_result = if args.fix {
std::process::Command::new("cargo")
.args(["clippy", "--fix", "--allow-dirty", "--allow-staged"])
.current_dir(project.root())
.status()
} else {
std::process::Command::new("cargo")
.args(["clippy", "--all-targets", "--", "-D", "warnings"])
.current_dir(project.root())
.status()
};
match clippy_result {
Ok(status) if status.success() => {
println!("✅ Rust linting passed");
}
Ok(_) => {
println!("❌ Rust linting failed");
all_passed = false;
}
Err(e) => {
println!("⚠️ Could not run clippy: {}", e);
println!(" Install with: rustup component add clippy");
}
}
println!();
println!("Validating configs (mecha10.json + node configs)...");
match crate::config_validation::validate_config(None) {
Ok(target) => {
println!("✅ Config validation passed ({})", target.display());
}
Err(e) => {
println!("❌ Config validation failed:");
println!("{:#}", e);
all_passed = false;
}
}
println!();
println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
if all_passed {
println!("✅ All linting checks passed!");
} else {
println!("❌ Some linting checks failed");
if !args.fix {
println!();
println!("Run with --fix to automatically fix issues:");
println!(" mecha10 lint --fix");
}
return Err(anyhow::anyhow!("Linting failed"));
}
println!();
Ok(())
}