use std::path::Path;
use crate::error::Result;
use crate::git::cli::GitCli;
use crate::git::porcelain::parse_submodule_status;
pub fn uninitialized(git: &dyn GitCli, worktree_dir: &Path) -> Result<Vec<String>> {
let output = git.run_raw(worktree_dir, &["submodule", "status"])?;
if !output.success {
return Ok(Vec::new());
}
Ok(parse_submodule_status(&output.stdout)
.into_iter()
.filter(|s| s.is_uninitialized())
.map(|s| s.path)
.collect())
}
pub fn update_init(git: &dyn GitCli, worktree_dir: &Path) -> Result<()> {
git.run(
worktree_dir,
&["submodule", "update", "--init", "--recursive"],
)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::git::cli::RealGit;
use crate::testutil::TestRepo;
#[test]
fn no_submodules_yields_empty() {
let repo = TestRepo::init();
assert!(uninitialized(&RealGit, repo.root()).unwrap().is_empty());
}
#[test]
fn reports_uninitialized_submodule() {
let repo = TestRepo::init();
repo.add_submodule("libs/sub");
repo.deinit_submodule("libs/sub");
let pending = uninitialized(&RealGit, repo.root()).unwrap();
assert_eq!(pending, vec!["libs/sub".to_string()]);
}
#[test]
fn update_init_populates_submodule() {
let repo = TestRepo::init();
repo.add_submodule("libs/sub");
repo.deinit_submodule("libs/sub");
assert!(!repo.root().join("libs/sub/sub.txt").exists());
update_init(&RealGit, repo.root()).unwrap();
assert!(repo.root().join("libs/sub/sub.txt").exists());
assert!(uninitialized(&RealGit, repo.root()).unwrap().is_empty());
}
#[test]
fn uninitialized_is_empty_outside_a_repo() {
let dir = tempfile::tempdir().unwrap();
assert!(uninitialized(&RealGit, dir.path()).unwrap().is_empty());
}
}