#[cfg(feature = "dhat-heap")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
use clap::Parser;
#[derive(Parser, Debug)]
#[command(
name = "forjar",
version,
about = "Rust-native Infrastructure as Code — bare-metal first, BLAKE3 state, provenance tracing"
)]
struct Cli {
#[arg(short, long, global = true, action = clap::ArgAction::Count)]
verbose: u8,
#[arg(long, global = true)]
no_color: bool,
#[command(subcommand)]
command: forjar::cli::Commands,
}
fn main() {
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();
let cli = Cli::parse();
let no_color = cli.no_color || std::env::var("NO_COLOR").is_ok();
if let Err(e) = forjar::cli::dispatch(cli.command, cli.verbose, no_color) {
let code = classify_exit_code(&e);
eprintln!("error: {e}");
std::process::exit(code);
}
}
fn classify_exit_code(error: &str) -> i32 {
if error.contains("validation error") || error.contains("YAML parse error") {
3
} else if error.contains("SSH") || error.contains("connection") || error.contains("transport") {
4
} else if error.contains("partial") || error.contains("some resources failed") {
2
} else if error.contains("drift detected") {
10
} else {
1
}
}