use oa_cli::{Report, arguments, prepare}; use std::{ io::{self, Write}, path::Path, process::ExitCode, }; fn human_report(report: &Report, show_diff: bool) -> io::Result<()> { let mut err = io::stderr().lock(); for d in &report.diagnostics { let at = d .location .as_ref() .map(|l| { format!( "{}:{}:{}", l.path, l.line.unwrap_or(0), l.column.unwrap_or(0) ) }) .unwrap_or_else(|| report.entry.clone()); writeln!( err, "{at}: {}[{}] ({}): {}", d.severity, d.code, d.coordinate_space, d.message )?; } writeln!( err, "{}: {} file changes; {} identities to stabilize", report.status, report.changes.len(), report.identities_to_stabilize )?; if let Some(migration) = &report.migration { writeln!( err, "Source migration: schema {} → {} (separate from identity stabilization)", migration.from_schema, migration.to_schema )?; } for note in &report.notes { writeln!(err, "{note}")?; } if show_diff { let mut out = io::stdout().lock(); for change in &report.changes { write!(out, "{}", change.diff)?; } out.flush()?; } err.flush() } fn run() -> io::Result { let args: Vec<_> = std::env::args_os().skip(1).collect(); if args.len() == 1 && (args[0] == "--help" || args[0] == "-h") { io::stdout().write_all(oa_cli::HELP.as_bytes())?; return Ok(0); } if args.len() == 1 && args[0] == "--version" { writeln!(io::stdout(), "arcadia {}", env!("CARGO_PKG_VERSION"))?; return Ok(0); } let json = args.iter().any(|a| a == "--json"); let mut displayed = false; let report = match arguments(&args) { Err(error) => Report::failure(Path::new(""), "usage", 2, "usage", error), Ok(args) => match prepare(&args.entry, args.operation) { Err(report) => *report, Ok(prepared) => { if args.write { if !args.json { human_report(prepared.report(), true)?; displayed = true; } prepared.write() } else { prepared.into_report() } } }, }; if json { serde_json::to_writer_pretty(io::stdout().lock(), &report)?; writeln!(io::stdout())?; } else { human_report(&report, !displayed)?; } Ok(report.exit_code) } fn main() -> ExitCode { match run() { Ok(code) => ExitCode::from(code), Err(error) => { let _ = writeln!(io::stderr(), "Output failed: {error}"); ExitCode::from(3) } } }