use clap::Args as ClapArgs;
use std::path::Path;
use crate::cli::output;
use crate::qual_file::{self, find_project_root};
use crate::scoring;
#[derive(ClapArgs)]
pub struct Args {
pub artifact: String,
#[arg(long, default_value = "human")]
pub format: String,
#[arg(long)]
pub graph: Option<String>,
#[arg(long)]
pub no_ignore: bool,
}
pub fn run(args: Args) -> crate::Result<()> {
let root = find_project_root(Path::new("."));
let graph = crate::cli::config::load_graph(args.graph.as_deref(), root.as_deref());
let discover_root = root.as_deref().unwrap_or(Path::new("."));
let all_qual_files = qual_file::discover(discover_root, !args.no_ignore)?;
let records = qual_file::find_records_for(&args.artifact, &all_qual_files);
if records.is_empty() {
return Err(crate::Error::Validation(format!(
"No records found for '{}'",
args.artifact
)));
}
let scores = scoring::effective_scores(&graph, &all_qual_files);
let owned_records: Vec<crate::attestation::Record> =
records.iter().map(|r| (*r).clone()).collect();
let report = scores
.get(&args.artifact)
.cloned()
.unwrap_or(scoring::ScoreReport {
raw: scoring::raw_score(&owned_records),
effective: scoring::raw_score(&owned_records),
limiting_path: None,
});
if args.format == "json" {
println!(
"{}",
output::show_json(&args.artifact, &report, &owned_records)
);
return Ok(());
}
println!();
println!(" {}", args.artifact);
println!(" Raw score: {}", report.raw);
if let Some(ref path) = report.limiting_path {
println!(
" Effective score: {} (limited by {})",
report.effective,
path.join(" -> ")
);
} else {
println!(" Effective score: {}", report.effective);
}
let active = scoring::filter_superseded(&owned_records);
println!();
println!(" Records ({}):", active.len());
for record in &active {
if let Some(att) = record.as_attestation() {
let date = att.created_at.format("%Y-%m-%d");
let issuer_short = att
.issuer
.strip_prefix("mailto:")
.and_then(|e| e.split('@').next())
.unwrap_or(&att.issuer);
println!(
" {} {} {:?} {} {}",
output::format_score(att.body.score),
att.body.kind,
att.body.summary,
issuer_short,
date,
);
} else if let Some(epoch) = record.as_epoch() {
let date = epoch.created_at.format("%Y-%m-%d");
println!(
" {} epoch {:?} {} {}",
output::format_score(epoch.body.score),
epoch.body.summary,
epoch.issuer,
date,
);
}
}
println!();
Ok(())
}