use crate::fleet::error::{Result, SuperGitError};
use crate::fleet::git::{SubmoduleOps, SubmoduleTree};
use crate::fleet::output::Formatter;
use crate::prelude::*;
pub fn execute<P: AsRef<Path>>(
repo_root: P,
recursive: bool,
dry_run: bool,
verbose: bool,
) -> Result<()> {
let tree = SubmoduleTree::discover(&repo_root)?;
let candidates: Vec<_> = tree
.top_down()
.iter()
.filter(|node| recursive || node.depth == 0)
.collect();
let pending: Vec<_> = candidates.iter().filter(|node| !node.initialized).collect();
Formatter::print_info(&format!(
"Initializing {} of {} known submodule(s){}",
pending.len(),
candidates.len(),
if recursive { " (recursively)" } else { "" }
));
if recursive && !pending.is_empty() {
Formatter::print_info(
"Submodules nested inside these will be discovered once their parent is checked out",
);
}
if dry_run {
Formatter::print_warning("DRY RUN: No changes will be made");
for node in &pending {
Formatter::print_info(&format!("Would initialize '{}'", node.label()));
}
return Ok(());
}
let skipped = candidates.len() - pending.len();
let outcome = SubmoduleOps::init_tree(&repo_root, recursive, |node| {
if verbose {
Formatter::print_submodule_header(node.label());
}
})?;
for name in &outcome.initialized {
Formatter::print_success(&format!("Initialized '{}'", name));
}
for (name, err) in &outcome.failures {
Formatter::print_error(&format!("Failed to initialize '{}': {}", name, err));
}
Formatter::print_summary(outcome.initialized.len(), outcome.failures.len(), skipped);
if !outcome.failures.is_empty() {
return Err(SuperGitError::Other(format!(
"{} submodule(s) failed to initialize",
outcome.failures.len()
)));
}
Ok(())
}