Skip to main content

stackless_cloud/
source_ref.rs

1//! Operator-side source-ref checkout helpers (Render/Vercel verify checkouts).
2
3use std::path::Path;
4
5use stackless_core::substrate::SubstrateFault;
6
7/// Whether a verify checkout at `path` still matches `commit` (`.git/HEAD`).
8pub fn present(path: &str, commit: &str) -> bool {
9    let path = Path::new(path);
10    if !path.exists() {
11        return false;
12    }
13    std::fs::read_to_string(path.join(".git/HEAD"))
14        .map(|head| head.trim() == commit)
15        .unwrap_or(false)
16}
17
18/// Remove a verify checkout directory. Missing path is success (idempotent).
19pub fn destroy(path: &str) -> Result<(), SubstrateFault> {
20    match std::fs::remove_dir_all(path) {
21        Ok(()) => Ok(()),
22        Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(()),
23        Err(err) => Err(SubstrateFault {
24            code: stackless_core::fault::codes::LOCAL_GIT_CHECKOUT_FAILED,
25            message: format!("cannot remove verify checkout {path}: {err}"),
26            remediation: format!("remove {path} by hand, then re-run `stackless down`"),
27            context: Box::default(),
28        }),
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn present_requires_matching_head() {
38        let dir = tempfile::tempdir().unwrap();
39        std::fs::create_dir_all(dir.path().join(".git")).unwrap();
40        std::fs::write(dir.path().join(".git/HEAD"), "abc\n").unwrap();
41        assert!(present(dir.path().to_str().unwrap(), "abc"));
42        assert!(!present(dir.path().to_str().unwrap(), "other"));
43    }
44
45    #[test]
46    fn destroy_missing_is_ok() {
47        destroy("/tmp/stackless-source-ref-missing-test-path").unwrap();
48    }
49}