From 6c3235e17b1bad265fc407d9bdb673122c3bada3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 22 Feb 2026 18:56:01 +0900 Subject: feat(audit): display version info in audit output Use previously stored but unused fields: show installed_version in advisory tables/plain/JSON output, and package version in abandoned package output. Remove unused unlockable_ids field from LockTransaction. Co-Authored-By: Claude Opus 4.6 --- crates/mozart/src/commands/audit.rs | 47 +++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'crates/mozart/src/commands/audit.rs') diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs index 2faec19..a26f579 100644 --- a/crates/mozart/src/commands/audit.rs +++ b/crates/mozart/src/commands/audit.rs @@ -44,14 +44,12 @@ struct PackageEntry { /// An advisory that matched an installed package version. struct MatchedAdvisory { advisory: SecurityAdvisory, - #[allow(dead_code)] installed_version: String, } /// An abandoned package found during audit. struct AbandonedPackage { name: String, - #[allow(dead_code)] version: String, replacement: Option, } @@ -416,6 +414,7 @@ fn render_table(result: &AuditResult) { let label_width = 17usize; let rows: Vec<(&str, String)> = vec![ ("Package", adv.package_name.clone()), + ("Version", matched.installed_version.clone()), ("Severity", adv.severity.clone().unwrap_or_default()), ("Advisory ID", adv.advisory_id.clone()), ( @@ -458,7 +457,14 @@ fn render_table(result: &AuditResult) { println!("{}", mozart_core::console::highlight(&header)); println!(); - let label_width = 20usize; + let name_width = 20usize; + let ver_width = result + .abandoned + .iter() + .map(|a| a.version.len()) + .max() + .unwrap_or(0) + .max("Version".len()); let repl_width = result .abandoned .iter() @@ -473,17 +479,21 @@ fn render_table(result: &AuditResult) { .max("Suggested Replacement".len()); println!( - "| {: println!("{} is abandoned. Use {} instead.", pkg.name, repl), - None => println!("{} is abandoned. No replacement was suggested.", pkg.name), + Some(repl) => println!("{} ({}) is abandoned. Use {} instead.", pkg.name, pkg.version, repl), + None => println!("{} ({}) is abandoned. No replacement was suggested.", pkg.name, pkg.version), } } } @@ -556,14 +569,18 @@ fn render_json(result: &AuditResult) -> anyhow::Result<()> { advisories_map.insert(pkg_name.clone(), serde_json::Value::Array(arr)); } - // Build abandoned map: package_name -> replacement_or_null + // Build abandoned map: package_name -> { version, replacement } let mut abandoned_map: serde_json::Map = serde_json::Map::new(); for pkg in &result.abandoned { let repl = match &pkg.replacement { Some(s) => serde_json::Value::String(s.clone()), None => serde_json::Value::Null, }; - abandoned_map.insert(pkg.name.clone(), repl); + let entry = serde_json::json!({ + "version": pkg.version, + "replacement": repl, + }); + abandoned_map.insert(pkg.name.clone(), entry); } let output = serde_json::json!({ @@ -593,8 +610,8 @@ fn render_summary(result: &AuditResult) { for pkg in &result.abandoned { match &pkg.replacement { - Some(repl) => println!("{} is abandoned. Use {} instead.", pkg.name, repl), - None => println!("{} is abandoned. No replacement was suggested.", pkg.name), + Some(repl) => println!("{} ({}) is abandoned. Use {} instead.", pkg.name, pkg.version, repl), + None => println!("{} ({}) is abandoned. No replacement was suggested.", pkg.name, pkg.version), } } } -- cgit v1.3.1