use anyhow::Result;
use cleanlib_client::{config, transport};
use comfy_table::{presets, ContentArrangement, Table};
use crate::render::terminal::{stdout_is_tty, style_decision};
pub async fn run(
since: Option<String>,
decision: Option<String>,
ecosystem: Option<String>,
output: String,
) -> Result<()> {
let path = config::default_path();
let cfg = config::load_with_env_overrides(path.as_deref())?;
let client = transport::Client::from_config(&cfg)?;
let resp = client
.audit(since.as_deref(), decision.as_deref(), ecosystem.as_deref())
.await?;
match output.as_str() {
"json" => println!("{}", serde_json::to_string_pretty(&resp)?),
_ => {
if resp.entries.is_empty() {
println!("(no audit entries match the given filters)");
} else {
let mut table = Table::new();
let preset = if stdout_is_tty() {
presets::UTF8_BORDERS_ONLY
} else {
presets::NOTHING
};
table
.load_preset(preset)
.set_content_arrangement(ContentArrangement::Dynamic)
.set_header(vec![
"AT", "REQUEST_ID", "ECOSYSTEM", "PACKAGE", "VERSION", "DECISION", "REASON",
]);
for e in &resp.entries {
table.add_row(vec![
e.at.clone(),
e.request_id.clone(),
e.ecosystem.clone(),
e.package.clone(),
e.version.clone(),
style_decision(&e.decision),
e.reason.clone(),
]);
}
println!("{table}");
}
if let Some(cursor) = &resp.next_cursor {
eprintln!("# more results available; next_cursor={}", cursor);
}
}
}
Ok(())
}