use crate::transaction_git::{GitContext, GitRequest, run_git};
use std::ffi::OsString;
use std::path::{Path, PathBuf};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct GitReply {
pub code: Option<i32>,
pub stdout: Vec<u8>,
pub stderr: Vec<u8>,
}
pub trait GitRunner {
fn run(&self, arguments: &[&str], input: Option<&[u8]>, index_file: Option<&Path>) -> Result<GitReply, String>;
}
pub struct ContextRunner<'a> {
pub context: &'a GitContext,
pub cwd: &'a Path,
pub without_prefix: bool,
pub object_directory: Option<&'a Path>,
pub environment: Vec<(OsString, OsString)>,
}
impl GitRunner for ContextRunner<'_> {
fn run(&self, arguments: &[&str], input: Option<&[u8]>, index_file: Option<&Path>) -> Result<GitReply, String> {
let mut request: GitRequest = GitRequest::new(self.cwd, arguments);
request.without_prefix = self.without_prefix;
request.object_directory = self.object_directory.map(Path::to_path_buf);
request.environment.clone_from(&self.environment);
request.input = input.map(<[u8]>::to_vec);
request.index = index_file.map(PathBuf::from);
let output = match run_git(self.context, &request) {
Ok(done) => done,
Err(error) => return Err(format!("git {} could not start: {error}", arguments.join(" "))),
};
return Ok(GitReply { code: output.code, stdout: output.stdout, stderr: output.stderr });
}
}
pub fn config_options(prefix: &[OsString]) -> Vec<OsString> {
let mut kept: Vec<OsString> = Vec::new();
let mut tokens = prefix.iter();
while let Some(token) = tokens.next() {
if token == "-c"
&& let Some(setting) = tokens.next()
{
kept.push(token.clone());
kept.push(setting.clone());
}
}
return kept;
}