A library for writing host-specific, single-binary configuration management and deployment tools
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.

66 lines
1.7 KiB

use crate::command_runner::CommandRunner;
use crate::symbols::Symbol;
use async_trait::async_trait;
use std::error::Error;
use std::ffi::OsStr;
use std::fmt;
use std::path::Path;
#[derive(Debug)]
pub struct GitSubmodules<'a, P, C> {
target: P,
command_runner: &'a C,
}
impl<'a, P, C> GitSubmodules<'a, P, C> {
pub const fn new(target: P, command_runner: &'a C) -> Self {
Self {
target,
command_runner,
}
}
}
impl<P: AsRef<Path>, C: CommandRunner> fmt::Display for GitSubmodules<'_, P, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Submodules for {}", self.target.as_ref().display())
}
}
impl<P: AsRef<Path>, C: CommandRunner> GitSubmodules<'_, P, C> {
async fn _run_in_target_repo(&self, args: &[&OsStr]) -> Result<Vec<u8>, Box<dyn Error>> {
let mut new_args: Vec<&OsStr> = vec![];
new_args.extend_from_slice(args!["-C", self.target.as_ref()]);
new_args.extend_from_slice(args);
self.command_runner.get_output("git", &new_args).await
}
}
#[async_trait(?Send)]
impl<P: AsRef<Path>, C: CommandRunner> Symbol for GitSubmodules<'_, P, C> {
async fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
if !self.target.as_ref().exists() {
return Ok(false);
}
let output = String::from_utf8(
self
._run_in_target_repo(args!["submodule", "status"])
.await?,
)?;
Ok(
output
.lines()
.all(|line| line.is_empty() || line.starts_with(' ')),
)
}
async fn execute(&self) -> Result<(), Box<dyn Error>> {
self
._run_in_target_repo(args!["submodule", "update", "--init"])
.await?;
Ok(())
}
}
#[cfg(test)]
mod test {}