diff --git a/Cargo.toml b/Cargo.toml index e8a7f2a..53d0208 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,3 @@ name = "schematics" version = "0.1.0" authors = ["Adrian Heine "] - -[dependencies] diff --git a/src/lib.rs b/src/lib.rs index 16d5ac5..0e691f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,11 @@ trivial_casts, trivial_numeric_casts, unsafe_code, unstable_features, unused_extern_crates, unused_import_braces, unused_qualifications, -unused_results, variant_size_differences +variant_size_differences +)] + +#![warn( +unused_results )] /* diff --git a/src/symbols/git.rs b/src/symbols/git.rs new file mode 100644 index 0000000..957f44a --- /dev/null +++ b/src/symbols/git.rs @@ -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, 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 { + 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 { +} diff --git a/src/symbols/mod.rs b/src/symbols/mod.rs index 90e2643..7fa1f0b 100644 --- a/src/symbols/mod.rs +++ b/src/symbols/mod.rs @@ -4,5 +4,6 @@ pub trait Symbol { fn execute(&self) -> Result<(), Self::Error>; } +pub mod git; pub mod user; pub mod systemd;