use crate::cli::output::Output;
use crate::core::manifest::Manifest;
use crate::core::repo::{filter_repos, get_manifest_repo_info, RepoInfo};
use crate::git::{
branch::{branch_exists, checkout_branch, create_and_checkout_branch},
open_repo,
};
use std::path::Path;
pub fn run_checkout(
workspace_root: &Path,
manifest: &Manifest,
branch_name: &str,
create: bool,
repos_filter: Option<&[String]>,
group_filter: Option<&[String]>,
) -> anyhow::Result<()> {
let action = if create {
"Creating and checking out"
} else {
"Checking out"
};
let mut repos: Vec<RepoInfo> =
filter_repos(manifest, workspace_root, repos_filter, group_filter, false);
let include_manifest = match repos_filter {
None => true,
Some(filter) => filter.iter().any(|r| r == "manifest"),
};
if include_manifest {
if let Some(manifest_repo) = get_manifest_repo_info(manifest, workspace_root) {
repos.push(manifest_repo);
}
}
Output::header(&format!(
"{} '{}' in {} repos...",
action,
branch_name,
repos.len()
));
println!();
let mut success_count = 0;
let mut _skip_count = 0;
for repo in &repos {
if !repo.exists() {
Output::warning(&format!("{}: not cloned", repo.name));
_skip_count += 1;
continue;
}
match open_repo(&repo.absolute_path) {
Ok(git_repo) => {
let exists = branch_exists(&git_repo, branch_name);
if create {
if exists {
match checkout_branch(&git_repo, branch_name) {
Ok(()) => {
Output::success(&format!(
"{}: checked out (already exists)",
repo.name
));
success_count += 1;
}
Err(e) => Output::error(&format!("{}: {}", repo.name, e)),
}
} else {
match create_and_checkout_branch(&git_repo, branch_name) {
Ok(()) => {
Output::success(&format!("{}: created and checked out", repo.name));
success_count += 1;
}
Err(e) => Output::error(&format!("{}: {}", repo.name, e)),
}
}
} else {
if !exists {
Output::info(&format!("{}: branch doesn't exist, skipping", repo.name));
_skip_count += 1;
continue;
}
match checkout_branch(&git_repo, branch_name) {
Ok(()) => {
Output::success(&repo.name);
success_count += 1;
}
Err(e) => Output::error(&format!("{}: {}", repo.name, e)),
}
}
}
Err(e) => Output::error(&format!("{}: {}", repo.name, e)),
}
}
println!();
println!(
"Switched {}/{} repos to {}",
success_count,
repos.len(),
Output::branch_name(branch_name)
);
Ok(())
}