From 6111096a8c5e1530d90f57cef2ee7bdfa5548c48 Mon Sep 17 00:00:00 2001 From: eiiko6 Date: Sat, 21 Feb 2026 19:36:28 +0100 Subject: [PATCH] improved todo display --- src/analysis.rs | 47 ++++++++++++++++++++++++++++++++++++++++++----- src/cli.rs | 6 +++++- src/main.rs | 4 ++-- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/analysis.rs b/src/analysis.rs index 643bb79..cc1820b 100644 --- a/src/analysis.rs +++ b/src/analysis.rs @@ -90,20 +90,57 @@ impl WikiGraph { println!("}}"); } - pub fn check_dead_links(&self) { - let mut found_issues = false; + pub fn check_dead_links(&self, reverse: bool) { + let mut missing_targets: HashMap<&String, Vec<&String>> = HashMap::new(); for (source, targets) in &self.edges { for target in targets { if !self.nodes.contains_key(target) { - println!("{} -> ❌ {}", source.bold().cyan(), target.red()); - found_issues = true; + missing_targets.entry(target).or_default().push(source); } } } - if !found_issues { + if missing_targets.is_empty() { println!("{}", "✅ No broken links found!".green().bold()); + return; + } + + let mut sorted_missing: Vec<_> = missing_targets.into_iter().collect(); + sorted_missing.sort_by(|a, b| b.1.len().cmp(&a.1.len()).then_with(|| a.0.cmp(b.0))); + + for (target, sources) in &sorted_missing { + let count = sources.len(); + let sources_list = sources + .iter() + .map(|s| s.as_str()) + .collect::>() + .join(", ") + .dimmed(); + + let target_styled = format!("❌ {}", target).red().bold(); + + if reverse { + println!("{} ({}) -> {}", sources_list, count, target_styled); + } else { + println!("{} ({}) <- {}", target_styled, count, sources_list); + } + } + + // Hint + println!(); + if let Some((top_target, sources)) = sorted_missing.first() { + let count = sources.len(); + println!( + "{}", + format!( + "Hint: Start working on '{}' as it has {} link{} pointing to it.", + top_target.red().bold(), + count, + if count > 1 { "s" } else { "" } + ) + .italic() + ); } } } diff --git a/src/cli.rs b/src/cli.rs index 52b8699..ea5ea82 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -32,7 +32,11 @@ pub enum Commands { /// Output a DOT graph of the wiki connections Graph {}, /// List broken links - Todo {}, + Todo { + /// Invert the display: "Sources -> Target" instead of "Target <- Sources" + #[arg(short, long)] + reverse: bool, + }, /// Manage wiki entries Entry { #[command(subcommand)] diff --git a/src/main.rs b/src/main.rs index dabea1c..6243cc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -126,9 +126,9 @@ async fn main() -> anyhow::Result<()> { let graph = analysis::WikiGraph::new(abs_path).await?; graph.print_dot(); } - Commands::Todo {} => { + Commands::Todo { reverse } => { let graph = analysis::WikiGraph::new(abs_path).await?; - graph.check_dead_links(); + graph.check_dead_links(reverse); } Commands::Entry { cmd } => { entry::handle(cmd, abs_path).await?;