use crate::template::GitRunner;
use std::io;
use std::path::Path;
pub trait BranchInspector {
fn exists(&self, repo: &Path, branch: &str, git: &dyn GitRunner) -> io::Result<bool>;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct GitInspector;
impl BranchInspector for GitInspector {
fn exists(&self, repo: &Path, branch: &str, git: &dyn GitRunner) -> io::Result<bool> {
Ok(crate::workspace::agent_exists(repo, branch, git))
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::RefCell;
use std::path::PathBuf;
struct RecordingGit {
invocations: RefCell<Vec<(PathBuf, Vec<String>)>>,
result: io::Result<()>,
}
impl GitRunner for RecordingGit {
fn run(&self, dest: &Path, args: &[&str]) -> io::Result<()> {
self.invocations.borrow_mut().push((
dest.to_path_buf(),
args.iter().map(|s| (*s).to_owned()).collect(),
));
match &self.result {
Ok(()) => Ok(()),
Err(e) => Err(io::Error::new(e.kind(), e.to_string())),
}
}
fn run_capture(&self, _: &Path, _: &[&str]) -> io::Result<String> {
unreachable!("inspector never calls run_capture")
}
}
fn ok_git() -> RecordingGit {
RecordingGit {
invocations: RefCell::new(Vec::new()),
result: Ok(()),
}
}
fn err_git() -> RecordingGit {
RecordingGit {
invocations: RefCell::new(Vec::new()),
result: Err(io::Error::other("boom")),
}
}
#[test]
fn exists_true_on_zero_exit_and_probes_the_agents_ref_in_repo_git() {
let git = ok_git();
assert!(
GitInspector
.exists(&PathBuf::from("/w"), "br", &git)
.unwrap()
);
let invocations = git.invocations.borrow();
assert_eq!(invocations[0].0, PathBuf::from("/w/repo.git"));
assert_eq!(
invocations[0].1,
vec!["rev-parse", "--verify", "--quiet", "refs/heads/agents/br"]
);
}
#[test]
fn exists_false_on_nonzero_exit() {
let git = err_git();
assert!(
!GitInspector
.exists(&PathBuf::from("/w"), "br", &git)
.unwrap()
);
}
}