use std::sync::OnceLock;
use worktrunk::git::{CiPlatform, Repository};
use super::{CiBranchName, PrStatus, azure, gitea, github, gitlab, tool_available};
static CI_TOOLS: OnceLock<CiToolsAvailable> = OnceLock::new();
struct CiToolsAvailable {
gh: bool,
glab: bool,
tea: bool,
az: bool,
}
impl CiToolsAvailable {
fn get() -> &'static Self {
CI_TOOLS.get_or_init(|| Self {
gh: tool_available("gh", &["--version"]),
glab: tool_available("glab", &["--version"]),
tea: tool_available("tea", &["--version"]),
az: tool_available("az", &["--version"]),
})
}
}
fn is_tool_available(platform: CiPlatform) -> bool {
match platform {
CiPlatform::GitHub => CiToolsAvailable::get().gh,
CiPlatform::GitLab => CiToolsAvailable::get().glab,
CiPlatform::Gitea => CiToolsAvailable::get().tea,
CiPlatform::AzureDevOps => CiToolsAvailable::get().az,
}
}
fn detect_pr_mr(
platform: CiPlatform,
repo: &Repository,
branch: &CiBranchName,
local_head: &str,
) -> Option<PrStatus> {
match platform {
CiPlatform::GitHub => github::detect_github(repo, branch, local_head),
CiPlatform::GitLab => gitlab::detect_gitlab(repo, branch, local_head),
CiPlatform::Gitea => gitea::detect_gitea_pr(repo, branch, local_head),
CiPlatform::AzureDevOps => azure::detect_azure_pr(repo, branch, local_head),
}
}
fn detect_branch(
platform: CiPlatform,
repo: &Repository,
branch: &CiBranchName,
local_head: &str,
) -> Option<PrStatus> {
match platform {
CiPlatform::GitHub => github::detect_github_commit_checks(repo, branch, local_head),
CiPlatform::GitLab => gitlab::detect_gitlab_pipeline(repo, &branch.name, local_head),
CiPlatform::Gitea => gitea::detect_gitea_commit_status(repo, branch, local_head),
CiPlatform::AzureDevOps => azure::detect_azure_pipeline(repo, branch, local_head),
}
}
pub(super) fn detect_ci(
platform: CiPlatform,
repo: &Repository,
branch: &CiBranchName,
local_head: &str,
has_upstream: bool,
) -> Option<PrStatus> {
if !is_tool_available(platform) {
return None;
}
if let Some(status) = detect_pr_mr(platform, repo, branch, local_head) {
return Some(status);
}
if has_upstream {
return detect_branch(platform, repo, branch, local_head);
}
None
}