Skip to main content

ralph/cli/queue/
show.rs

1//! Queue show subcommand.
2//!
3//! Responsibilities:
4//! - Define CLI arguments for displaying a single task.
5//! - Load queue + done data and render a task in JSON or compact form.
6//!
7//! Not handled here:
8//! - Queue persistence beyond reading files.
9//! - Validation or mutation beyond reading.
10//! - Any task editing behavior.
11//!
12//! Invariants/assumptions:
13//! - Queue files are valid and already validated by the loader.
14//! - Task IDs are matched after trimming whitespace.
15
16use anyhow::{Result, anyhow};
17use clap::Args;
18
19use crate::cli::load_and_validate_queues_read_only;
20use crate::config::Resolved;
21use crate::{outpututil, queue};
22
23use super::QueueShowFormat;
24
25/// Arguments for `ralph queue show`.
26#[derive(Args)]
27#[command(
28    after_long_help = "Examples:\n  ralph queue show RQ-0001\n  ralph queue show RQ-0001 --format compact"
29)]
30pub struct QueueShowArgs {
31    /// Task ID to show.
32    #[arg(value_name = "TASK_ID")]
33    pub task_id: String,
34
35    /// Output format.
36    #[arg(long, value_enum, default_value_t = QueueShowFormat::Json)]
37    pub format: QueueShowFormat,
38}
39
40pub(crate) fn show_task(resolved: &Resolved, task_id: &str, format: QueueShowFormat) -> Result<()> {
41    let (queue_file, done_file) = load_and_validate_queues_read_only(resolved, true)?;
42    let done_ref = done_file
43        .as_ref()
44        .filter(|d| !d.tasks.is_empty() || resolved.done_path.exists());
45
46    let task = queue::find_task_across(&queue_file, done_ref, task_id)
47        .ok_or_else(|| anyhow!("{}", crate::error_messages::task_not_found(task_id.trim())))?;
48
49    match format {
50        QueueShowFormat::Json => {
51            let rendered = serde_json::to_string_pretty(task)?;
52            print!("{rendered}");
53        }
54        QueueShowFormat::Compact => {
55            println!("{}", outpututil::format_task_compact(task));
56        }
57    }
58    Ok(())
59}
60
61pub(crate) fn handle(resolved: &Resolved, args: QueueShowArgs) -> Result<()> {
62    show_task(resolved, &args.task_id, args.format)
63}