| 
						
						
						
					 | 
				
				 | 
				
					@ -0,0 +1,74 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::fmt;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::io;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use command_runner::CommandRunner;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use symbols::Symbol;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					pub struct GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  target: &'a str,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  source: &'a str,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  branch: &'a str,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  command_runner: &'a CommandRunner
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					impl<'a> GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pub fn new(target: &'a str, source: &'a str, branch: &'a str, command_runner: &'a CommandRunner) -> GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    GitCheckout {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      target: target,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      source: source,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      branch: branch,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      command_runner: command_runner
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					impl<'a> fmt::Display for GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    write!(f, "Checkout {} (branch {}) into {}", self.source, self.branch, self.target)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::fs::metadata;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					impl<'a> GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  fn _run_in_target_repo(&self, args: &[&str]) -> Result<Vec<u8>, io::Error> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let mut new_args = vec!["-C", self.target];
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    new_args.extend_from_slice(args);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    self.command_runner.run_with_args("git", &new_args).map(|res| res.stdout)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					impl<'a> Symbol for GitCheckout<'a> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  type Error = io::Error;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  fn target_reached(&self) -> Result<bool, Self::Error> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if let Err(e) = metadata(self.target) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return if e.kind() == io::ErrorKind::NotFound {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Ok(false)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Err(e)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    try!(self._run_in_target_repo(&["fetch", self.source, self.branch]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let fetch_head = try!(self._run_in_target_repo(&["rev-parse", "FETCH_HEAD"]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let head = try!(self._run_in_target_repo(&["rev-parse", "HEAD"]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Ok(fetch_head == head)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  fn execute(&self) -> Result<(), Self::Error> {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if let Err(e) = metadata(self.target) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return if e.kind() == io::ErrorKind::NotFound {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        try!(self.command_runner.run_with_args("git", &["clone", "-b", self.branch, self.source, self.target]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Ok(())
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Err(e)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    try!(self._run_in_target_repo(&["fetch", self.source, self.branch]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    try!(self._run_in_target_repo(&["merge", "FETCH_HEAD"]));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Ok(())
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#[cfg(test)]
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					mod test {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}
 |