improved todo display
This commit is contained in:
@@ -90,20 +90,57 @@ impl WikiGraph {
|
|||||||
println!("}}");
|
println!("}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_dead_links(&self) {
|
pub fn check_dead_links(&self, reverse: bool) {
|
||||||
let mut found_issues = false;
|
let mut missing_targets: HashMap<&String, Vec<&String>> = HashMap::new();
|
||||||
|
|
||||||
for (source, targets) in &self.edges {
|
for (source, targets) in &self.edges {
|
||||||
for target in targets {
|
for target in targets {
|
||||||
if !self.nodes.contains_key(target) {
|
if !self.nodes.contains_key(target) {
|
||||||
println!("{} -> ❌ {}", source.bold().cyan(), target.red());
|
missing_targets.entry(target).or_default().push(source);
|
||||||
found_issues = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found_issues {
|
if missing_targets.is_empty() {
|
||||||
println!("{}", "✅ No broken links found!".green().bold());
|
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::<Vec<&str>>()
|
||||||
|
.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()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ pub enum Commands {
|
|||||||
/// Output a DOT graph of the wiki connections
|
/// Output a DOT graph of the wiki connections
|
||||||
Graph {},
|
Graph {},
|
||||||
/// List broken links
|
/// List broken links
|
||||||
Todo {},
|
Todo {
|
||||||
|
/// Invert the display: "Sources -> Target" instead of "Target <- Sources"
|
||||||
|
#[arg(short, long)]
|
||||||
|
reverse: bool,
|
||||||
|
},
|
||||||
/// Manage wiki entries
|
/// Manage wiki entries
|
||||||
Entry {
|
Entry {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let graph = analysis::WikiGraph::new(abs_path).await?;
|
let graph = analysis::WikiGraph::new(abs_path).await?;
|
||||||
graph.print_dot();
|
graph.print_dot();
|
||||||
}
|
}
|
||||||
Commands::Todo {} => {
|
Commands::Todo { reverse } => {
|
||||||
let graph = analysis::WikiGraph::new(abs_path).await?;
|
let graph = analysis::WikiGraph::new(abs_path).await?;
|
||||||
graph.check_dead_links();
|
graph.check_dead_links(reverse);
|
||||||
}
|
}
|
||||||
Commands::Entry { cmd } => {
|
Commands::Entry { cmd } => {
|
||||||
entry::handle(cmd, abs_path).await?;
|
entry::handle(cmd, abs_path).await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user