10 changed files with 248 additions and 16 deletions
			
			
		- 
					4src/symbols/dir.rs
 - 
					49src/symbols/dir_for.rs
 - 
					1src/symbols/file.rs
 - 
					0src/symbols/git/checkout.rs
 - 
					2src/symbols/git/mod.rs
 - 
					50src/symbols/git/submodules.rs
 - 
					117src/symbols/list.rs
 - 
					3src/symbols/mod.rs
 - 
					9src/symbols/nginx/server.rs
 - 
					23src/symbols/systemd/node_js_user_service.rs
 
@ -0,0 +1,49 @@ | 
			
		|||||
 | 
				use std::error::Error;
 | 
			
		||||
 | 
				use std::fmt;
 | 
			
		||||
 | 
				use std::fs;
 | 
			
		||||
 | 
				use std::os::unix::fs::MetadataExt;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				use users::get_user_by_name;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				use symbols::Symbol;
 | 
			
		||||
 | 
				use symbols::dir::Dir;
 | 
			
		||||
 | 
				use command_runner::CommandRunner;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				pub struct DirFor<'a, D> where D: AsRef<str> + fmt::Display {
 | 
			
		||||
 | 
				  dir: Dir<D>,
 | 
			
		||||
 | 
				  path: D,
 | 
			
		||||
 | 
				  user_name: &'a str,
 | 
			
		||||
 | 
				  command_runner: &'a CommandRunner
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a, D> DirFor<'a, D> where D: AsRef<str> + fmt::Display + Clone {
 | 
			
		||||
 | 
				  pub fn new(path: D, user_name: &'a str, command_runner: &'a CommandRunner) -> Self {
 | 
			
		||||
 | 
				    DirFor { dir: Dir::new(path.clone()), path: path, user_name: user_name, command_runner: command_runner }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a, D> Symbol for DirFor<'a, D> where D: AsRef<str> + fmt::Display {
 | 
			
		||||
 | 
				  fn target_reached(&self) -> Result<bool, Box<Error>> {
 | 
			
		||||
 | 
				    match self.dir.target_reached() {
 | 
			
		||||
 | 
				      Ok(true) => {
 | 
			
		||||
 | 
				        let actual_uid = fs::metadata(self.path.as_ref()).unwrap().uid();
 | 
			
		||||
 | 
				        let target_uid = get_user_by_name(self.user_name).unwrap().uid();
 | 
			
		||||
 | 
				        Ok(actual_uid == target_uid)
 | 
			
		||||
 | 
				      },
 | 
			
		||||
 | 
				      res => res
 | 
			
		||||
 | 
				    }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  fn execute(&self) -> Result<(), Box<Error>> {
 | 
			
		||||
 | 
				    try!(self.dir.execute());
 | 
			
		||||
 | 
				    try!(self.command_runner.run_with_args("chown", &[self.user_name, self.path.as_ref()]));
 | 
			
		||||
 | 
				    Ok(())
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a, D> fmt::Display for DirFor<'a, D> where D: AsRef<str> + fmt::Display {
 | 
			
		||||
 | 
				  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
 | 
			
		||||
 | 
				    write!(f, "Dir {} for {}", self.path, self.user_name)
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
@ -0,0 +1,2 @@ | 
			
		|||||
 | 
				pub mod checkout;
 | 
			
		||||
 | 
				pub mod submodules;
 | 
			
		||||
@ -0,0 +1,50 @@ | 
			
		|||||
 | 
				use std::error::Error;
 | 
			
		||||
 | 
				use std::fmt;
 | 
			
		||||
 | 
				use std::io;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				use command_runner::CommandRunner;
 | 
			
		||||
 | 
				use symbols::Symbol;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				pub struct GitSubmodules<'a> {
 | 
			
		||||
 | 
				  target: &'a str,
 | 
			
		||||
 | 
				  command_runner: &'a CommandRunner
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> GitSubmodules<'a> {
 | 
			
		||||
 | 
				  pub fn new(target: &'a str, command_runner: &'a CommandRunner) -> GitSubmodules<'a> {
 | 
			
		||||
 | 
				    GitSubmodules {
 | 
			
		||||
 | 
				      target: target,
 | 
			
		||||
 | 
				      command_runner: command_runner
 | 
			
		||||
 | 
				    }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> fmt::Display for GitSubmodules<'a> {
 | 
			
		||||
 | 
				  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
			
		||||
 | 
				    write!(f, "Submodules for {}", self.target)
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> GitSubmodules<'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 GitSubmodules<'a> {
 | 
			
		||||
 | 
				  fn target_reached(&self) -> Result<bool, Box<Error>> {
 | 
			
		||||
 | 
				    let output = try!(self._run_in_target_repo(&["submodule", "status"]));
 | 
			
		||||
 | 
				    Ok(String::from_utf8(output).unwrap().lines().all(|line| line.len() == 0 || line.starts_with(' ')))
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  fn execute(&self) -> Result<(), Box<Error>> {
 | 
			
		||||
 | 
				    try!(self._run_in_target_repo(&["submodule", "update", "--init"]));
 | 
			
		||||
 | 
				    Ok(())
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#[cfg(test)]
 | 
			
		||||
 | 
				mod test {
 | 
			
		||||
 | 
				}
 | 
			
		||||
@ -0,0 +1,117 @@ | 
			
		|||||
 | 
				use std::error::Error;
 | 
			
		||||
 | 
				use std::fmt;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				use symbols::Symbol;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				pub struct List<'a> {
 | 
			
		||||
 | 
				  symbols: Vec<Box<Symbol + 'a>>
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> List<'a> {
 | 
			
		||||
 | 
				  pub fn new(symbols: Vec<Box<Symbol + 'a>>) -> Self {
 | 
			
		||||
 | 
				    List { symbols: symbols }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> Symbol for List<'a> {
 | 
			
		||||
 | 
				  fn target_reached(&self) -> Result<bool, Box<Error>> {
 | 
			
		||||
 | 
				    for symbol in &self.symbols {
 | 
			
		||||
 | 
				      match symbol.target_reached() {
 | 
			
		||||
 | 
				        Ok(false) => return Ok(false),
 | 
			
		||||
 | 
				        Err(e) => return Err(e),
 | 
			
		||||
 | 
				        Ok(true) => {}
 | 
			
		||||
 | 
				      }
 | 
			
		||||
 | 
				    }
 | 
			
		||||
 | 
				    Ok(true)
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  fn execute(&self) -> Result<(), Box<Error>> {
 | 
			
		||||
 | 
				    for symbol in &self.symbols {
 | 
			
		||||
 | 
				      try!(symbol.execute());
 | 
			
		||||
 | 
				    }
 | 
			
		||||
 | 
				    Ok(())
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<'a> fmt::Display for List<'a> {
 | 
			
		||||
 | 
				  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
 | 
			
		||||
 | 
				    try!(write!(f, "List [ "));
 | 
			
		||||
 | 
				    for symbol in &self.symbols {
 | 
			
		||||
 | 
				      try!(write!(f, "{} ", symbol));
 | 
			
		||||
 | 
				    }
 | 
			
		||||
 | 
				    write!(f, "]")
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				/*
 | 
			
		||||
 | 
				#[cfg(test)]
 | 
			
		||||
 | 
				mod test {
 | 
			
		||||
 | 
				  use std::error::Error;
 | 
			
		||||
 | 
				  use std::fmt;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  use symbols::Symbol;
 | 
			
		||||
 | 
				  use symbols::hook::List;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  struct ErrSymbol(String);
 | 
			
		||||
 | 
				  impl Symbol for ErrSymbol {
 | 
			
		||||
 | 
				    fn target_reached(&self) -> Result<bool, Box<Error>> { Err(self.0.clone().into()) }
 | 
			
		||||
 | 
				    fn execute(&self) -> Result<(), Box<Error>> { Err(self.0.clone().into()) }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				  impl fmt::Display for ErrSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  struct OkSymbol(bool);
 | 
			
		||||
 | 
				  impl Symbol for OkSymbol {
 | 
			
		||||
 | 
				    fn target_reached(&self) -> Result<bool, Box<Error>> { Ok(self.0) }
 | 
			
		||||
 | 
				    fn execute(&self) -> Result<(), Box<Error>> { Ok(()) }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				  impl fmt::Display for OkSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn first_target_reached_fails() {
 | 
			
		||||
 | 
				    let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "first");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn first_target_not_reached() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(false), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), false);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_target_reached_fails() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(true), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "second");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_target_not_reached() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(true), OkSymbol(false)).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), false);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn everything_reached() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(true), OkSymbol(true)).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), true);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn first_execute_fails() {
 | 
			
		||||
 | 
				    let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "first");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_execute_fails() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(true), ErrSymbol("second".into())).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "second");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn everything_executes() {
 | 
			
		||||
 | 
				    let res = List::new(OkSymbol(true), OkSymbol(true)).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), ());
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				*/
 | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue