use crate::cli::StatusArgs;
use crate::error::{CliError, CliResult};
use crate::pipeline_state::ops::Stores;
use crate::status::{StatusInputs, StatusReport, assemble, render};
use chrono::Utc;
pub async fn run(args: StatusArgs) -> CliResult<()> {
let report = build(&args).await?;
let text = if args.load.json {
serde_json::to_string_pretty(&report)
.map_err(|e| CliError::Internal(format!("serializing JSON output: {e}")))?
+ "\n"
} else {
render::render(&report)
+ &report
.notes
.iter()
.map(|n| format!(" note: {n}\n"))
.collect::<String>()
};
print!("{}", crate::secrets::registry::redact(&text));
match report.exit_code {
0 => Ok(()),
code => Err(CliError::StatusUnhealthy {
code,
health: report.health.as_str().to_string(),
}),
}
}
pub async fn build(args: &StatusArgs) -> CliResult<StatusReport> {
let (cfg, target, _) = super::state::load(args.config.as_deref(), &args.load).await?;
let auth = crate::auth_catalog::build_auth_catalog(cfg.auth.as_ref())?;
let stores = Stores::build(&target, None)
.await
.map_err(|e| crate::secrets::registry::redact(&e.to_string()).into_owned());
#[allow(unused_mut)]
let mut notes: Vec<String> = Vec::new();
#[allow(unused_mut)]
let (mut history, mut active_runs) = (Vec::new(), Vec::new());
#[cfg(feature = "catalog")]
if let Some(spec) = &cfg.catalog {
match crate::catalog::connect_from_spec(spec).await {
Ok(handle) => {
match crate::status::history::read(handle.store.as_ref(), &target.pipeline).await {
Ok((h, a)) => {
history = h;
active_runs = a;
}
Err(e) => notes.push(format!("run history unreadable: {e}")),
}
}
Err(e) => notes.push(format!("run history unreachable: {e}")),
}
}
let inputs = StatusInputs {
now: Utc::now(),
row: args.row.as_deref(),
probe: args.probe,
auth: &auth,
history,
active_runs,
};
let mut report = assemble(&target, stores.as_ref().map_err(Clone::clone), &inputs).await?;
report.notes.extend(notes);
Ok(report)
}