use std::collections::BTreeMap;
use std::io;
use std::path::Path;
pub const FILE_NAME: &str = "shield.lock";
const HEADER: &str = "\
# shield.lock — just-shield가 박제한 태그→SHA 대응. 직접 수정하지 말 것.
# 갱신: just-shield lock
";
#[derive(Default)]
pub struct Lockfile {
pub entries: BTreeMap<String, String>,
}
impl Lockfile {
pub fn key(repo: &str, git_ref: &str) -> String {
format!("{repo}@{git_ref}")
}
pub fn get(&self, repo: &str, git_ref: &str) -> Option<&str> {
self.entries
.get(&Self::key(repo, git_ref))
.map(|s| s.as_str())
}
}
pub fn load(root: &Path) -> io::Result<Option<Lockfile>> {
let path = root.join(FILE_NAME);
if !path.is_file() {
return Ok(None);
}
let content = std::fs::read_to_string(path)?;
let mut entries = BTreeMap::new();
for line in content.lines() {
let line = line.trim();
if line.is_empty() || line.starts_with('#') {
continue;
}
if let Some((key, sha)) = line.split_once(' ') {
entries.insert(key.to_string(), sha.trim().to_string());
}
}
Ok(Some(Lockfile { entries }))
}
pub fn save(root: &Path, lockfile: &Lockfile) -> io::Result<()> {
let mut out = String::from(HEADER);
for (key, sha) in &lockfile.entries {
out.push_str(&format!("{key} {sha}\n"));
}
std::fs::write(root.join(FILE_NAME), out)
}