use cuenv_codeowners::provider::CodeOwnersProvider;
use std::path::Path;
#[cfg(feature = "bitbucket")]
use cuenv_bitbucket::BitbucketCodeOwnersProvider;
#[cfg(feature = "buildkite")]
use cuenv_buildkite::BuildkiteCIProvider;
#[cfg(feature = "github")]
use cuenv_github::GitHubCodeOwnersProvider;
#[cfg(feature = "gitlab")]
use cuenv_gitlab::GitLabCodeOwnersProvider;
#[must_use]
pub fn detect_code_owners_provider(repo_root: &Path) -> Box<dyn CodeOwnersProvider> {
#[cfg(feature = "github")]
if repo_root.join(".github").is_dir() {
return Box::new(GitHubCodeOwnersProvider);
}
#[cfg(feature = "gitlab")]
if repo_root.join(".gitlab-ci.yml").exists() {
return Box::new(GitLabCodeOwnersProvider);
}
#[cfg(feature = "bitbucket")]
if repo_root.join("bitbucket-pipelines.yml").exists() {
return Box::new(BitbucketCodeOwnersProvider);
}
#[cfg(feature = "github")]
return Box::new(GitHubCodeOwnersProvider);
#[cfg(all(not(feature = "github"), feature = "gitlab"))]
return Box::new(GitLabCodeOwnersProvider);
#[cfg(all(
not(feature = "github"),
not(feature = "gitlab"),
feature = "bitbucket"
))]
return Box::new(BitbucketCodeOwnersProvider);
#[cfg(not(any(feature = "github", feature = "gitlab", feature = "bitbucket")))]
compile_error!("At least one platform feature must be enabled (github, gitlab, or bitbucket)");
}
#[must_use]
#[cfg(feature = "github")]
pub fn detect_ci_provider(
from_ref: Option<String>,
) -> std::sync::Arc<dyn cuenv_ci::provider::CIProvider> {
use cuenv_ci::provider::CIProvider;
use std::sync::Arc;
#[cfg(feature = "buildkite")]
if let Some(provider) = BuildkiteCIProvider::detect() {
return Arc::new(provider);
}
if let Some(provider) = cuenv_github::GitHubCIProvider::detect() {
return Arc::new(provider);
}
if let Some(base_ref) = from_ref {
Arc::new(cuenv_ci::provider::LocalProvider::with_base_ref(base_ref))
} else {
Arc::new(
cuenv_ci::provider::LocalProvider::detect().unwrap_or_else(|| {
cuenv_ci::provider::LocalProvider::with_base_ref("main".to_string())
}),
)
}
}
#[must_use]
#[cfg(not(feature = "github"))]
pub fn detect_ci_provider(
from_ref: Option<String>,
) -> std::sync::Arc<dyn cuenv_ci::provider::CIProvider> {
use cuenv_ci::provider::CIProvider;
use std::sync::Arc;
#[cfg(feature = "buildkite")]
if let Some(provider) = BuildkiteCIProvider::detect() {
return Arc::new(provider);
}
if let Some(base_ref) = from_ref {
Arc::new(cuenv_ci::provider::LocalProvider::with_base_ref(base_ref))
} else {
Arc::new(
cuenv_ci::provider::LocalProvider::detect().unwrap_or_else(|| {
cuenv_ci::provider::LocalProvider::with_base_ref("main".to_string())
}),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::tempdir;
#[test]
#[cfg(feature = "github")]
fn test_detect_github() {
let temp = tempdir().unwrap();
fs::create_dir(temp.path().join(".github")).unwrap();
let provider = detect_code_owners_provider(temp.path());
assert_eq!(provider.output_path(), ".github/CODEOWNERS");
}
#[test]
#[cfg(feature = "gitlab")]
fn test_detect_gitlab() {
let temp = tempdir().unwrap();
fs::write(temp.path().join(".gitlab-ci.yml"), "").unwrap();
let provider = detect_code_owners_provider(temp.path());
assert_eq!(provider.output_path(), "CODEOWNERS");
assert_eq!(
provider.section_style(),
cuenv_codeowners::SectionStyle::Bracket
);
}
#[test]
#[cfg(feature = "bitbucket")]
fn test_detect_bitbucket() {
let temp = tempdir().unwrap();
fs::write(temp.path().join("bitbucket-pipelines.yml"), "").unwrap();
let provider = detect_code_owners_provider(temp.path());
assert_eq!(provider.output_path(), "CODEOWNERS");
assert_eq!(
provider.section_style(),
cuenv_codeowners::SectionStyle::Comment
);
}
#[test]
#[cfg(feature = "github")]
fn test_detect_default_github() {
let temp = tempdir().unwrap();
let provider = detect_code_owners_provider(temp.path());
assert_eq!(provider.output_path(), ".github/CODEOWNERS");
}
}