use crate::cli::output::Output;
use crate::core::repo::RepoInfo;
use crate::git::{open_repo, path_exists};
use git2::Repository;
pub enum RepoVisitResult {
Success(String),
Skipped(String),
Error(String),
}
pub struct RepoOpSummary {
pub success_count: usize,
pub skip_count: usize,
pub error_count: usize,
}
pub fn for_each_repo<F>(repos: &[RepoInfo], quiet: bool, mut op: F) -> RepoOpSummary
where
F: FnMut(&RepoInfo, &Repository) -> RepoVisitResult,
{
let mut summary = RepoOpSummary {
success_count: 0,
skip_count: 0,
error_count: 0,
};
for repo in repos {
if !path_exists(&repo.absolute_path) {
if !quiet {
Output::warning(&format!("{}: not cloned", repo.name));
}
summary.skip_count += 1;
continue;
}
match open_repo(&repo.absolute_path) {
Ok(git_repo) => match op(repo, &git_repo) {
RepoVisitResult::Success(msg) => {
if !quiet {
Output::success(&msg);
}
summary.success_count += 1;
}
RepoVisitResult::Skipped(msg) => {
if !quiet {
Output::info(&msg);
}
summary.skip_count += 1;
}
RepoVisitResult::Error(msg) => {
Output::error(&msg);
summary.error_count += 1;
}
},
Err(e) => {
Output::error(&format!("{}: {}", repo.name, e));
summary.error_count += 1;
}
}
}
summary
}
pub fn for_each_repo_path<F>(repos: &[RepoInfo], quiet: bool, mut op: F) -> RepoOpSummary
where
F: FnMut(&RepoInfo) -> RepoVisitResult,
{
let mut summary = RepoOpSummary {
success_count: 0,
skip_count: 0,
error_count: 0,
};
for repo in repos {
if !path_exists(&repo.absolute_path) {
if !quiet {
Output::warning(&format!("{}: not cloned", repo.name));
}
summary.skip_count += 1;
continue;
}
match op(repo) {
RepoVisitResult::Success(msg) => {
if !quiet {
Output::success(&msg);
}
summary.success_count += 1;
}
RepoVisitResult::Skipped(msg) => {
if !quiet {
Output::info(&msg);
}
summary.skip_count += 1;
}
RepoVisitResult::Error(msg) => {
Output::error(&msg);
summary.error_count += 1;
}
}
}
summary
}