wsb 0.258.6441

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
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(())
}