Skip to main content

ralph/cli/queue/
repair.rs

1//! Queue repair subcommand.
2
3use anyhow::Result;
4use clap::Args;
5
6use crate::config::Resolved;
7use crate::queue;
8
9/// Arguments for `ralph queue repair`.
10#[derive(Args)]
11pub struct RepairArgs {
12    /// Show what would be changed without writing to disk.
13    #[arg(long)]
14    pub dry_run: bool,
15}
16
17pub(crate) fn handle(resolved: &Resolved, force: bool, args: RepairArgs) -> Result<()> {
18    let _queue_lock = queue::acquire_queue_lock(&resolved.repo_root, "queue repair", force)?;
19    let report = queue::repair_queue(
20        &resolved.queue_path,
21        &resolved.done_path,
22        &resolved.id_prefix,
23        resolved.id_width,
24        args.dry_run,
25    )?;
26
27    if report.is_empty() {
28        log::info!("No issues found. Queue is healthy.");
29    } else {
30        log::info!("Repair report:");
31        if report.fixed_tasks > 0 {
32            log::info!("  Fixed missing fields in {} task(s)", report.fixed_tasks);
33        }
34        if report.fixed_timestamps > 0 {
35            log::info!(
36                "  Fixed invalid timestamps in {} task(s)",
37                report.fixed_timestamps
38            );
39        }
40        if !report.remapped_ids.is_empty() {
41            log::info!("  Remapped {} duplicate ID(s):", report.remapped_ids.len());
42            for (old, new) in &report.remapped_ids {
43                log::info!("    {} -> {}", old, new);
44            }
45        }
46        if args.dry_run {
47            log::info!("Dry run: no changes written to disk.");
48        } else {
49            log::info!("Repaired queue written to disk.");
50        }
51    }
52
53    Ok(())
54}