#![forbid(unsafe_code)]
#![allow(clippy::multiple_crate_versions)]
use clap::Parser;
use rust_doctor::cli::{Cli, Command};
use rust_doctor::{config, run};
use std::process::ExitCode;
fn main() -> ExitCode {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.with_writer(std::io::stderr)
.init();
let cli = Cli::parse();
if matches!(cli.command, Some(Command::Setup)) {
return run::handle_setup();
}
if cli.install_deps {
return run::handle_install_deps();
}
if let Some(code) = run::handle_mcp_flag(&cli) {
return code;
}
let (_target_dir, project_info, file_config) = match run::bootstrap_project(&cli) {
Ok(result) => result,
Err(e) => {
eprintln!("Error: {e}");
return ExitCode::from(run::EXIT_SCAN_ERROR);
}
};
let effective_config = if cli.no_project_config {
None
} else {
file_config.as_ref()
};
let resolved = config::resolve_config(&cli, effective_config);
let scan_result = match run::run_scan(&cli, &project_info, &resolved) {
Ok(result) => result,
Err(e) => {
eprintln!("Error: {e}");
return ExitCode::from(run::EXIT_SCAN_ERROR);
}
};
run::apply_fixes_if_requested(&cli, &scan_result);
if let Err(e) = run::emit_output(&cli, &scan_result, &resolved) {
eprintln!("Error: {e}");
return ExitCode::from(run::EXIT_SCAN_ERROR);
}
run::emit_plan_if_requested(&cli, &scan_result);
if let Some(code) = run::check_score_gate(&scan_result, resolved.score_fail_below) {
return code;
}
if let Some(code) = run::check_fail_on_gate(&scan_result, resolved.fail_on) {
return code;
}
ExitCode::SUCCESS
}