wsb 0.258.6441

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
use crate::fleet::config::GitModules;
use crate::fleet::error::{Result, SuperGitError};
use crate::fleet::output::Formatter;
use crate::prelude::*;

fn stage_catalog(repo_root: &Path, catalog_path: &Path) -> Result<()> {
    let repo = crate::git_backend::discover_repo(repo_root)
        .map_err(|e| SuperGitError::Other(format!("git discover failed: {}", e)))?;
    let path_str = catalog_path.to_string_lossy().to_string();
    crate::git_backend::stage_paths(&repo, &[path_str])
        .map_err(|e| SuperGitError::Other(format!("git add failed: {}", e)))?;
    Ok(())
}

pub fn execute(repo_root: &Path, output: Option<&Path>, git_add: bool, quiet: bool) -> Result<()> {
    let gitmodules = match GitModules::parse(repo_root) {
        Ok(gm) => gm,
        Err(SuperGitError::NoSubmodules) => GitModules {
            entries: Vec::new(),
            submodules: Vec::new(),
        },
        Err(e) => return Err(e),
    };

    let mut failed = 0usize;

    if gitmodules.submodules.is_empty() {
        let catalog_path = output
            .map(|p| p.to_path_buf())
            .unwrap_or_else(|| repo_root.join("TEST_CATALOG.md"));
        crate::catalogue::run(repo_root, Some(&catalog_path), quiet)
            .map_err(|e| SuperGitError::Other(e))?;
        if git_add && catalog_path.exists() {
            stage_catalog(repo_root, &catalog_path)?;
            if !quiet {
                Formatter::print_success(&format!("Staged {}", catalog_path.display()));
            }
        }
        return Ok(());
    }

    if !quiet {
        Formatter::print_info(&format!(
            "Generating test catalog for superproject + {} submodule(s)",
            gitmodules.submodules.len()
        ));
    }

    let super_catalog = output
        .map(|p| p.to_path_buf())
        .unwrap_or_else(|| repo_root.join("TEST_CATALOG.md"));

    if !quiet {
        Formatter::print_submodule_header("[SUPERPROJECT]");
    }
    match crate::catalogue::run(repo_root, Some(&super_catalog), quiet) {
        Ok(()) => {
            if git_add && super_catalog.exists() {
                if let Err(e) = stage_catalog(repo_root, &super_catalog) {
                    Formatter::print_error(&format!("git add failed for superproject: {}", e));
                    failed += 1;
                } else if !quiet {
                    Formatter::print_success(&format!("Staged {}", super_catalog.display()));
                }
            }
        }
        Err(e) => {
            Formatter::print_error(&format!("Superproject catalog failed: {}", e));
            failed += 1;
        }
    }

    for submodule in &gitmodules.submodules {
        let sub_path = repo_root.join(&submodule.path);
        if !sub_path.exists() {
            if !quiet {
                Formatter::print_warning(&format!(
                    "Submodule '{}' not initialized, skipping",
                    submodule.name
                ));
            }
            continue;
        }
        if !quiet {
            Formatter::print_submodule_header(&submodule.name);
        }
        let sub_catalog = sub_path.join("TEST_CATALOG.md");
        match crate::catalogue::run(&sub_path, Some(&sub_catalog), quiet) {
            Ok(()) => {
                if git_add && sub_catalog.exists() {
                    if let Err(e) = stage_catalog(&sub_path, &sub_catalog) {
                        Formatter::print_error(&format!(
                            "git add failed for '{}': {}",
                            submodule.name, e
                        ));
                        failed += 1;
                    } else if !quiet {
                        Formatter::print_success(&format!("Staged {}", sub_catalog.display()));
                    }
                }
            }
            Err(e) => {
                Formatter::print_error(&format!("Catalog failed for '{}': {}", submodule.name, e));
                failed += 1;
            }
        }
    }

    if failed > 0 {
        return Err(SuperGitError::Other(format!(
            "{} repo(s) failed to generate test catalog",
            failed
        )));
    }

    Ok(())
}