use std::path::Path;
use std::process::Command;
#[derive(Debug)]
pub struct GitOutput {
pub status: Option<i32>,
pub stdout: Vec<u8>,
pub stderr: Vec<u8>,
}
pub fn run_git(args: &[&str], cwd: &Path) -> GitOutput {
match Command::new("git").args(args).current_dir(cwd).output() {
Ok(out) => GitOutput {
status: out.status.code(),
stdout: out.stdout,
stderr: out.stderr,
},
Err(err) => GitOutput {
status: None,
stdout: Vec::new(),
stderr: format!("{err}").into_bytes(),
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn run_git_success_status_and_stdout() {
let res = run_git(
&["rev-parse", "--short", "HEAD"],
env!("CARGO_MANIFEST_DIR").as_ref(),
);
assert_eq!(res.status, Some(0));
assert!(String::from_utf8_lossy(&res.stdout).trim().len() > 3);
}
#[test]
fn run_git_failing_command_nonzero() {
let res = run_git(
&["rev-parse", "not-a-real-ref-xyz"],
env!("CARGO_MANIFEST_DIR").as_ref(),
);
assert_ne!(res.status, Some(0));
}
#[test]
fn run_git_spawn_error_surfaced() {
let res = run_git(
&["rev-parse", "HEAD"],
"/nonexistent-dir-for-rungit-test".as_ref(),
);
assert_eq!(res.status, None);
assert!(String::from_utf8_lossy(&res.stderr).contains("No such file or directory"));
}
}