use crate::fleet::error::Result;
use crate::fleet::git::{GitOps, SubmoduleOps, SubmoduleStatus, SubmoduleTree};
use crate::fleet::output::Formatter;
use crate::prelude::*;
use rayon::prelude::*;
pub fn execute<P: AsRef<Path> + Sync>(repo_root: P, _verbose: bool) -> Result<()> {
let tree = SubmoduleTree::discover_allow_empty(&repo_root)?;
let max_depth = tree
.top_down()
.iter()
.map(|node| node.depth + 1)
.max()
.unwrap_or(0);
let ignored = tree.ignored().len();
Formatter::print_info(&format!(
"Superproject + {} submodule(s) across {} level(s){}",
tree.len(),
max_depth,
if ignored == 0 {
String::new()
} else {
format!(" ({ignored} ignored)")
}
));
let repo = GitOps::open_repo(&repo_root)?;
let is_detached = GitOps::is_detached_head(&repo)?;
let current_branch = if is_detached {
None
} else {
Some(GitOps::current_branch(&repo)?)
};
let is_clean = GitOps::is_clean(&repo)?;
let uncommitted_files = if !is_clean {
GitOps::get_uncommitted_files(&repo)?
} else {
Vec::new()
};
let (ahead, behind) = if !is_detached {
GitOps::get_ahead_behind(&repo).unwrap_or((0, 0))
} else {
(0, 0)
};
let super_status = SubmoduleStatus {
name: "[SUPERPROJECT]".to_string(),
path: ".".to_string(),
current_branch,
is_clean,
is_detached,
ahead,
behind,
uncommitted_files,
exists: true,
depth: 0,
};
let mut statuses: Vec<_> = tree
.top_down()
.par_iter()
.map(SubmoduleOps::get_status)
.collect::<Result<Vec<_>>>()?;
statuses.insert(0, super_status);
Formatter::print_status(&statuses);
Ok(())
}