From f212ffc31f11eed09376e610cc853d4a0ebd5ba8 Mon Sep 17 00:00:00 2001 From: "Victor A." <52110451+cs50victor@users.noreply.github.com> Date: Sat, 30 May 2026 11:59:57 -0700 Subject: [PATCH] feat: add doctor subcommand for read-only optimization audit --- README.md | 1 + src/cli.rs | 3 ++ src/doctor.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 ++++++- 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/doctor.rs diff --git a/README.md b/README.md index f752706..269d72d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Run it inside a Cargo project (or anywhere, for the global suggestions): ```sh frd # report, then the interactive wizard frd report # print the system and project report, then exit +frd doctor # audit which optimizations are applied; exit non-zero if any are pending frd --dry-run # show every change as a diff, write and run nothing frd --yes # accept every applicable suggestion without prompting frd --root DIR # operate on DIR instead of the current directory diff --git a/src/cli.rs b/src/cli.rs index 70632f8..a46a67a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -28,4 +28,7 @@ pub struct Cli { pub enum Commands { /// Print the system and project report, then exit. Report, + + /// Audit which optimizations are applied, change nothing, and exit non-zero if any are pending. + Doctor, } diff --git a/src/doctor.rs b/src/doctor.rs new file mode 100644 index 0000000..bbdee7c --- /dev/null +++ b/src/doctor.rs @@ -0,0 +1,76 @@ +//! The `doctor` command: a read-only audit of which catalog optimizations are already +//! applied on this machine and project. Writes and runs nothing, and returns false when +//! any state-based optimization is still pending so the caller can exit non-zero, which +//! makes it usable as a CI or pre-commit check. + +use crate::catalog; +use crate::status_of; +use crate::suggestion::{Action, Status, Suggestion}; +use crate::system::SystemReport; +use console::{StyledObject, style}; + +/// Print the checkup. Returns true when every state-based optimization is applied. +pub fn run(report: &SystemReport) -> bool { + // Run actions (e.g. sweeping stale artifacts) are recurring maintenance, not a state we + // can detect as "done", so they never count toward the verdict. Check only the config- + // and tool-based items, which status_of can classify as applied or pending. + let (maintenance, checkable): (Vec, Vec) = catalog::build(report) + .into_iter() + .partition(|s| matches!(s.action, Action::Run(_))); + + println!("{}", style("Doctor: optimization checkup").bold().cyan()); + let mut pending = 0usize; + for s in &checkable { + let applied = status_of(report, s) == Status::AlreadyApplied; + if !applied { + pending += 1; + } + println!(" {} {} {}", mark(applied), tag(s), s.title); + } + + if !maintenance.is_empty() { + println!(); + println!("{}", style("Maintenance (re-run anytime):").dim()); + for s in &maintenance { + if let Action::Run(spec) = &s.action { + println!( + " {} {}", + style(format!("{}:", s.title)).dim(), + style(spec.display()).dim() + ); + } + } + } + + println!(); + let total = checkable.len(); + if pending == 0 { + println!( + "{}", + style(format!("All {total} optimizations applied; nothing to do.")).green() + ); + true + } else { + println!( + "{}", + style(format!( + "{}/{total} applied, {pending} pending. Run `frd` to apply them.", + total - pending + )) + .yellow() + ); + false + } +} + +fn mark(applied: bool) -> StyledObject<&'static str> { + if applied { + style("[ok]").green().bold() + } else { + style("[--]").red().bold() + } +} + +fn tag(s: &Suggestion) -> StyledObject { + style(format!("{:<5}", s.tag.label())).dim() +} diff --git a/src/main.rs b/src/main.rs index 6ef890f..93f37f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod catalog; mod cli; +mod doctor; mod runner; mod suggestion; mod system; @@ -25,6 +26,13 @@ fn main() -> Result<()> { return Ok(()); } + if matches!(args.command, Some(cli::Commands::Doctor)) { + if !doctor::run(&report) { + std::process::exit(1); + } + return Ok(()); + } + if !report.project.has_cargo_toml { println!( "{}", @@ -96,7 +104,7 @@ fn main() -> Result<()> { Ok(()) } -fn status_of(r: &SystemReport, s: &Suggestion) -> Status { +pub(crate) fn status_of(r: &SystemReport, s: &Suggestion) -> Status { match &s.action { Action::Toml(c) => { if toml_ops::is_applied(r, c) {