use std::process::{Command, ExitStatus, Stdio};
use std::{fmt, io};
use radicle::prelude::RepoId;
use radicle::storage::ReadStorage;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Expiry {
#[allow(dead_code)]
Now,
#[allow(dead_code)]
Seconds(usize),
Hours(usize),
#[allow(dead_code)]
Days(usize),
#[allow(dead_code)]
Weeks(usize),
}
impl Expiry {
const DEFAULT: Self = Expiry::Hours(1);
}
impl Default for Expiry {
fn default() -> Self {
Self::DEFAULT
}
}
impl fmt::Display for Expiry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[rustfmt::skip]
let (quantity, unit) = match self {
Self::Now => return f.write_str("now"),
Self::Seconds(quantity) => (quantity, "seconds"),
Self::Hours (quantity) => (quantity, "hours" ),
Self::Days (quantity) => (quantity, "days" ),
Self::Weeks (quantity) => (quantity, "weeks" ),
};
write!(f, "{quantity}.{unit}.ago")
}
}
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)
}