Skip to content

Commit cb7d714

Browse files
nikomatsakisclaude
andcommitted
feat: add issue caching infrastructure
Adds issue caching mechanism with .issues-*.json files and updates gitignore to exclude cache files and Claude settings. This provides the foundation for efficient issue data retrieval in subsequent blog post generation features. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 53c794b commit cb7d714

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@ target
33
.cache
44
src/api
55

6+
# Issue cache files
7+
.issues-*.json
8+
9+
# Claude Code settings
10+
.claude/
11+
612
# copied into the repo by `mdbook-mermaid` install:
713
/mermaid*.js

crates/rust-project-goals/src/gh/issues.rs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::BTreeSet, process::Command, str::FromStr};
1+
use std::{collections::BTreeSet, fs, process::Command, str::FromStr, time::SystemTime};
22

33
use chrono::NaiveDate;
44
use rust_project_goals_json::{GithubIssueState, Progress};
@@ -130,7 +130,60 @@ pub fn list_issues_in_milestone(
130130
repository: &Repository,
131131
timeframe: &str,
132132
) -> Result<Vec<ExistingGithubIssue>> {
133-
list_issues(repository, &[("-m", timeframe)])
133+
list_issues_cached(
134+
repository,
135+
&[("-m", timeframe)],
136+
Some(format!(".issues-{}.json", timeframe)),
137+
)
138+
}
139+
140+
/// Clear the cached issues for a given milestone/timeframe
141+
pub fn clear_milestone_issues_cache(timeframe: &str) -> Result<()> {
142+
let cache_file = format!(".issues-{}.json", timeframe);
143+
if std::path::Path::new(&cache_file).exists() {
144+
std::fs::remove_file(&cache_file)
145+
.with_str_context(format!("Failed to remove cache file {cache_file}"))?;
146+
}
147+
Ok(())
148+
}
149+
150+
pub fn list_issues_cached(
151+
repository: &Repository,
152+
filter: &[(&str, &str)],
153+
cache_file: Option<String>,
154+
) -> Result<Vec<ExistingGithubIssue>> {
155+
if let Some(ref cache_path) = cache_file {
156+
// Check if cache file exists and is less than 5 minutes old
157+
if let Ok(metadata) = fs::metadata(cache_path) {
158+
if let Ok(modified) = metadata.modified() {
159+
if let Ok(elapsed) = SystemTime::now().duration_since(modified) {
160+
if elapsed.as_secs() < 300 {
161+
// 5 minutes = 300 seconds
162+
// Try to read from cache
163+
if let Ok(cached_data) = fs::read_to_string(cache_path) {
164+
if let Ok(cached_issues) =
165+
serde_json::from_str::<Vec<ExistingGithubIssue>>(&cached_data)
166+
{
167+
return Ok(cached_issues);
168+
}
169+
}
170+
}
171+
}
172+
}
173+
}
174+
}
175+
176+
// Cache miss or expired - fetch from GitHub
177+
let issues = list_issues(repository, filter)?;
178+
179+
// Save to cache if cache_file is specified
180+
if let Some(ref cache_path) = cache_file {
181+
if let Ok(serialized) = serde_json::to_string_pretty(&issues) {
182+
let _ = fs::write(cache_path, serialized); // Ignore write errors
183+
}
184+
}
185+
186+
Ok(issues)
134187
}
135188

136189
pub fn list_issues(

0 commit comments

Comments
 (0)