103 lines
2.9 KiB
Rust
103 lines
2.9 KiB
Rust
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<u8> {
|
|
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)
|
|
}
|
|
}
|
|
}
|