You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.1 KiB
74 lines
2.1 KiB
use crate::command_runner::CommandRunner;
|
|
use crate::symbols::Symbol;
|
|
use std::borrow::Borrow;
|
|
use std::error::Error;
|
|
use std::ffi::OsStr;
|
|
use std::marker::PhantomData;
|
|
use std::path::Path;
|
|
|
|
#[derive(Debug)]
|
|
pub struct Checkout<_C, C, P, S, B> {
|
|
target: P,
|
|
source: S,
|
|
branch: B,
|
|
command_runner: C,
|
|
phantom: PhantomData<_C>,
|
|
}
|
|
|
|
impl<C, _C, P, S, B> Checkout<_C, C, P, S, B> {
|
|
pub fn new(target: P, source: S, branch: B, command_runner: C) -> Self {
|
|
Self {
|
|
target,
|
|
source,
|
|
branch,
|
|
command_runner,
|
|
phantom: PhantomData::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<C: CommandRunner, _C: Borrow<C>, P: AsRef<Path>, S, B> Checkout<C, _C, P, S, B> {
|
|
fn _run_in_target_repo(&self, args: &[impl AsRef<OsStr>]) -> Result<Vec<u8>, Box<dyn Error>> {
|
|
let mut new_args = vec![OsStr::new("-C"), self.target.as_ref().as_ref()];
|
|
new_args.extend(args.iter().map(AsRef::as_ref));
|
|
self.command_runner.borrow().get_output("git", &new_args)
|
|
}
|
|
}
|
|
|
|
impl<C: CommandRunner, _C: Borrow<C>, P: AsRef<Path>, S: AsRef<str>, B: AsRef<str>> Symbol
|
|
for Checkout<C, _C, P, S, B>
|
|
{
|
|
fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
|
|
if !self.target.as_ref().exists() {
|
|
return Ok(false);
|
|
}
|
|
self._run_in_target_repo(&["fetch", self.source.as_ref(), self.branch.as_ref()])?;
|
|
// git rev-list resolves tag objects
|
|
let fetch_head = self._run_in_target_repo(&["rev-list", "-1", "FETCH_HEAD"])?;
|
|
let head = self._run_in_target_repo(&["rev-list", "-1", "HEAD"])?;
|
|
Ok(fetch_head == head)
|
|
}
|
|
|
|
fn execute(&self) -> Result<(), Box<dyn Error>> {
|
|
if !self.target.as_ref().exists() {
|
|
return self.command_runner.borrow().run_successfully(
|
|
"git",
|
|
args![
|
|
"clone",
|
|
"--depth",
|
|
"1",
|
|
"-b",
|
|
self.branch.as_ref(),
|
|
self.source.as_ref(),
|
|
self.target.as_ref(),
|
|
],
|
|
);
|
|
}
|
|
self._run_in_target_repo(&["fetch", self.source.as_ref(), self.branch.as_ref()])?;
|
|
self._run_in_target_repo(&["merge", "FETCH_HEAD"])?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {}
|