Skip to main content

apm/cmd/
list.rs

1use anyhow::Result;
2use apm_core::config::resolve_identity;
3use std::path::Path;
4use crate::ctx::CmdContext;
5
6pub fn run(root: &Path, state_filter: Option<String>, unassigned: bool, all: bool, actionable_filter: Option<String>, no_aggressive: bool, mine: bool, author: Option<String>, owner: Option<String>) -> Result<()> {
7    let ctx = CmdContext::load(root, no_aggressive)?;
8
9    let mine_user: Option<String> = if mine {
10        Some(resolve_identity(root))
11    } else {
12        None
13    };
14    let author_filter = if mine { None } else { author };
15
16    let filtered = apm_core::ticket::list_filtered(
17        &ctx.tickets,
18        &ctx.config,
19        state_filter.as_deref(),
20        unassigned,
21        all,
22        actionable_filter.as_deref(),
23        author_filter.as_deref(),
24        owner.as_deref(),
25        mine_user.as_deref(),
26    );
27
28    let mut stale_tickets: Vec<(&str, &str)> = Vec::new();
29    let mut diverged_tickets: Vec<(&str, &str)> = Vec::new();
30
31    for t in &filtered {
32        let fm = &t.frontmatter;
33        let owner = fm.owner.as_deref().unwrap_or("-");
34        let base = match fm.target_branch.as_deref() {
35            Some(branch) => apm_core::epic::epic_id_from_branch(branch).to_owned(),
36            None => ctx.config.project.default_branch.clone(),
37        };
38        let id_display = if t.local_stale {
39            format!("*{}", fm.id)
40        } else {
41            fm.id.clone()
42        };
43        println!("{:<9} [{:<12}] {:<16} {:<12} {}", id_display, fm.state, owner, base, fm.title);
44
45        if t.local_stale {
46            stale_tickets.push((&fm.id, &fm.title));
47        }
48        if t.local_diverged {
49            diverged_tickets.push((&fm.id, &fm.title));
50        }
51    }
52
53    if !diverged_tickets.is_empty() {
54        eprintln!();
55        eprintln!("warning: local ref has diverged from origin on {} ticket(s) — showing local content:", diverged_tickets.len());
56        for (id, title) in &diverged_tickets {
57            eprintln!("    {}  {}", id, title);
58        }
59    }
60
61    if !stale_tickets.is_empty() {
62        println!();
63        println!("  * local ref behind origin — run `apm sync` to fast-forward:");
64        for (id, title) in &stale_tickets {
65            println!("      *{}  {}", id, title);
66        }
67    }
68
69    Ok(())
70}