Skip to main content

sr_ai/commands/
cache.rs

1use crate::cache::CacheManager;
2use crate::cache::store;
3use crate::git::GitRepo;
4use anyhow::Result;
5
6#[derive(Debug, clap::Args)]
7pub struct CacheArgs {
8    #[command(subcommand)]
9    pub command: CacheCommand,
10}
11
12#[derive(Debug, clap::Subcommand)]
13pub enum CacheCommand {
14    /// Show cached entries for this repo
15    Status,
16    /// Clear cached entries
17    Clear {
18        /// Clear cache for all repos, not just the current one
19        #[arg(long)]
20        all: bool,
21    },
22}
23
24pub fn run(args: &CacheArgs) -> Result<()> {
25    match &args.command {
26        CacheCommand::Status => status(),
27        CacheCommand::Clear { all } => clear(*all),
28    }
29}
30
31fn status() -> Result<()> {
32    let repo = GitRepo::discover()?;
33    let repo_root = repo.root();
34
35    let Some(dir) = store::cache_dir(repo_root) else {
36        println!("Cache directory could not be resolved.");
37        return Ok(());
38    };
39
40    let entries = store::list_entries(&dir)?;
41
42    if entries.is_empty() {
43        println!("No cached entries for this repository.");
44        return Ok(());
45    }
46
47    let now = store::now_secs();
48
49    println!("Cached commit plans ({} entries):", entries.len());
50    println!();
51    for entry in &entries {
52        let age_secs = now.saturating_sub(entry.created_at);
53        let age = format_age(age_secs);
54        let file_count: usize = entry.plan.commits.iter().map(|c| c.files.len()).sum();
55        let commit_count = entry.plan.commits.len();
56        println!(
57            "  {} — {} commit(s), {} file(s), backend={}, model={}, age={}",
58            &entry.state_key[..12],
59            commit_count,
60            file_count,
61            entry.backend,
62            entry.model,
63            age,
64        );
65    }
66
67    println!();
68    println!("Cache dir: {}", dir.display());
69
70    Ok(())
71}
72
73fn clear(all: bool) -> Result<()> {
74    if all {
75        let count = store::clear_all()?;
76        println!("Cleared {count} cached entries across all repositories.");
77    } else {
78        let repo = GitRepo::discover()?;
79        let cm = CacheManager::new(repo.root(), false, None, "", "");
80        match cm {
81            Some(cm) => {
82                let count = cm.clear()?;
83                println!("Cleared {count} cached entries for this repository.");
84            }
85            None => {
86                println!("Cache directory could not be resolved.");
87            }
88        }
89    }
90    Ok(())
91}
92
93fn format_age(secs: u64) -> String {
94    if secs < 60 {
95        format!("{secs}s")
96    } else if secs < 3600 {
97        format!("{}m", secs / 60)
98    } else {
99        format!("{}h", secs / 3600)
100    }
101}