Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
heartwood crates radicle-node src worker garbage.rs
use std::process::{Command, ExitStatus, Stdio};
use std::{fmt, io};

use radicle::prelude::RepoId;
use radicle::storage::ReadStorage;

/// Default expiry time for objects.
pub const EXPIRY_DEFAULT: Expiry = Expiry::Hours(1);

/// Expiry of objects for garbage collector.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Expiry {
    Now,
    Seconds(usize),
    Hours(usize),
    Days(usize),
    Weeks(usize),
}

impl Default for Expiry {
    fn default() -> Self {
        EXPIRY_DEFAULT
    }
}

impl fmt::Display for Expiry {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Now => f.write_str("now"),
            Self::Seconds(s) => write!(f, "{s}.seconds.ago"),
            Self::Hours(s) => write!(f, "{s}.hours.ago"),
            Self::Days(s) => write!(f, "{s}.days.ago"),
            Self::Weeks(s) => write!(f, "{s}.weeks.ago"),
        }
    }
}

/// Run Git garbage collector.
pub fn collect(storage: &impl ReadStorage, rid: RepoId, expiry: Expiry) -> io::Result<ExitStatus> {
    let git_dir = storage.path_of(&rid);
    let mut gc = Command::new("git");
    gc.current_dir(git_dir)
        .env_clear()
        .envs(std::env::vars().filter(|(key, _)| key == "PATH" || key.starts_with("GIT_TRACE")))
        .args(["gc", &format!("--prune={expiry}"), "--auto"])
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .stderr(Stdio::inherit());
    let mut child = gc.spawn()?;
    let status = child.wait()?;

    Ok(status)
}