use std::error::Error; use std::fmt; use std::path::Path; use command_runner::CommandRunner; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; pub struct GitSubmodules<'a, C: 'a + CommandRunner> { target: &'a str, command_runner: &'a C, } impl<'a, C: CommandRunner> GitSubmodules<'a, C> { pub fn new(target: &'a str, command_runner: &'a C) -> Self { GitSubmodules { target, command_runner, } } } impl<'a, C: CommandRunner> fmt::Display for GitSubmodules<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Submodules for {}", self.target) } } impl<'a, C: CommandRunner> GitSubmodules<'a, C> { fn _run_in_target_repo(&self, args: &[&str]) -> Result, Box> { let mut new_args = vec!["-C", self.target]; new_args.extend_from_slice(args); self.command_runner.get_output("git", &new_args) } } impl<'a, C: CommandRunner> Symbol for GitSubmodules<'a, C> { fn target_reached(&self) -> Result> { if !Path::new(self.target).exists() { return Ok(false); } let output = String::from_utf8(self._run_in_target_repo(&["submodule", "status"])?)?; Ok( output .lines() .all(|line| line.is_empty() || line.starts_with(' ')), ) } fn execute(&self) -> Result<(), Box> { self._run_in_target_repo(&["submodule", "update", "--init"])?; Ok(()) } fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box { Box::new(SymbolAction::new(runner, self)) } fn into_action<'b>(self: Box, runner: &'b dyn SymbolRunner) -> Box where Self: 'b, { Box::new(OwnedSymbolAction::new(runner, *self)) } } #[cfg(test)] mod test {}