Skip to content

Commit 3cf249c

Browse files
Create and use notes cache backend
1 parent 7e54cc9 commit 3cf249c

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

josh-core/src/cache.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ lazy_static! {
2222
static ref DB: std::sync::Mutex<Option<sled::Db>> = std::sync::Mutex::new(None);
2323
}
2424

25+
pub(crate) fn josh_commit_signature<'a>() -> JoshResult<git2::Signature<'a>> {
26+
Ok(if let Ok(time) = std::env::var("JOSH_COMMIT_TIME") {
27+
git2::Signature::new(
28+
"JOSH",
29+
"josh@josh-project.dev",
30+
&git2::Time::new(time.parse()?, 0),
31+
)?
32+
} else {
33+
git2::Signature::now("JOSH", "josh@josh-project.dev")?
34+
})
35+
}
36+
2537
static REF_CACHE: LazyLock<RwLock<HashMap<git2::Oid, HashMap<git2::Oid, git2::Oid>>>> =
2638
LazyLock::new(Default::default);
2739

josh-core/src/cache_notes.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use crate::JoshResult;
2+
use crate::cache::{CACHE_VERSION, CacheBackend};
3+
use crate::filter::Filter;
4+
5+
pub struct NotesCacheBackend {
6+
repo: std::sync::Mutex<git2::Repository>,
7+
}
8+
9+
impl NotesCacheBackend {
10+
pub fn new(repo_path: impl AsRef<std::path::Path>) -> JoshResult<Self> {
11+
let repo = git2::Repository::open(repo_path.as_ref())?;
12+
Ok(Self {
13+
repo: std::sync::Mutex::new(repo),
14+
})
15+
}
16+
}
17+
18+
fn is_note_eligible(oid: git2::Oid) -> bool {
19+
oid.as_bytes()[0] == 0
20+
}
21+
22+
fn note_path(key: git2::Oid) -> String {
23+
format!("refs/josh/{}/{}", CACHE_VERSION, key)
24+
}
25+
26+
impl CacheBackend for NotesCacheBackend {
27+
fn read(&self, filter: Filter, from: git2::Oid) -> JoshResult<Option<git2::Oid>> {
28+
let repo = self.repo.lock()?;
29+
let key = crate::filter::as_tree(&repo, filter)?;
30+
31+
if !is_note_eligible(from) {
32+
return Ok(None);
33+
}
34+
35+
if let Ok(note) = repo.find_note(Some(&note_path(key)), from) {
36+
let message = note.message().unwrap_or("");
37+
let result = git2::Oid::from_str(message)?;
38+
39+
Ok(Some(result))
40+
} else {
41+
Ok(None)
42+
}
43+
}
44+
45+
fn write(&self, filter: Filter, from: git2::Oid, to: git2::Oid) -> JoshResult<()> {
46+
let repo = self.repo.lock()?;
47+
let key = crate::filter::as_tree(&repo, filter)?;
48+
49+
if !is_note_eligible(from) {
50+
return Ok(());
51+
}
52+
53+
let signature = crate::cache::josh_commit_signature()?;
54+
55+
repo.note(
56+
&signature,
57+
&signature,
58+
Some(&note_path(key)),
59+
from,
60+
&to.to_string(),
61+
true,
62+
)?;
63+
64+
Ok(())
65+
}
66+
}

josh-core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ macro_rules! ok_or {
1818
extern crate rs_tracing;
1919

2020
pub mod cache;
21+
pub mod cache_notes;
2122
pub mod cache_sled;
2223
pub mod cache_stack;
2324
pub mod filter;

josh-filter/src/bin/josh-filter.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,21 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
178178

179179
let mut filterobj = josh::filter::parse(&specstr)?;
180180

181-
if !args.get_flag("no-cache") {
181+
let repo_path = {
182182
let repo = git2::Repository::open_from_env()?;
183-
josh::cache_sled::sled_load(repo.path())?;
183+
repo.path().to_path_buf()
184+
};
185+
186+
if !args.get_flag("no-cache") {
187+
josh::cache_sled::sled_load(&repo_path)?;
184188
}
185189

186-
let cache = std::sync::Arc::new(josh::cache_stack::CacheStack::default());
190+
let cache = std::sync::Arc::new(
191+
josh::cache_stack::CacheStack::new()
192+
.with_backend(josh::cache_sled::SledCacheBackend::default())
193+
.with_backend(josh::cache_notes::NotesCacheBackend::new(&repo_path)?),
194+
);
195+
187196
let mut transaction = josh::cache::TransactionContext::from_env(cache.clone())?.open(None)?;
188197

189198
let repo_for_hook = git2::Repository::open_ext(

0 commit comments

Comments
 (0)