62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
use anyhow::Result;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use std::fs;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct CacheManifest {
|
|
#[serde(default)]
|
|
pub git: HashMap<String, GitCacheEntry>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct GitCacheEntry {
|
|
pub path: PathBuf,
|
|
pub resolved_ref: String,
|
|
pub fetched_at: String,
|
|
}
|
|
|
|
impl CacheManifest {
|
|
pub fn load(cache_dir: &Path) -> Result<Self> {
|
|
let manifest_path = cache_dir.join("cache.json");
|
|
if !manifest_path.exists() {
|
|
return Ok(Self {
|
|
git: HashMap::new(),
|
|
});
|
|
}
|
|
let content = fs::read_to_string(&manifest_path)?;
|
|
let manifest = serde_json::from_str(&content)?;
|
|
Ok(manifest)
|
|
}
|
|
|
|
pub fn save(&self, cache_dir: &Path) -> Result<()> {
|
|
if !cache_dir.exists() {
|
|
fs::create_dir_all(cache_dir)?;
|
|
}
|
|
let manifest_path = cache_dir.join("cache.json");
|
|
let content = serde_json::to_string_pretty(self)?;
|
|
fs::write(manifest_path, content)?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub fn get_cache_root(project_root: &Path) -> PathBuf {
|
|
project_root.join("cache")
|
|
}
|
|
|
|
pub fn get_git_worktree_path(project_root: &Path, repo_url: &str) -> PathBuf {
|
|
let cache_root = get_cache_root(project_root);
|
|
let id = normalized_repo_id(repo_url);
|
|
cache_root.join("git").join(id).join("worktree")
|
|
}
|
|
|
|
fn normalized_repo_id(url: &str) -> String {
|
|
let mut hash = 0xcbf29ce484222325;
|
|
for b in url.as_bytes() {
|
|
hash ^= *b as u64;
|
|
hash = hash.wrapping_mul(0x100000001b3);
|
|
}
|
|
format!("{:016x}", hash)
|
|
}
|