use std::path::{Path, PathBuf};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Target {
Compose { file: PathBuf },
Actions { file: PathBuf },
Gitlab { file: PathBuf },
Circleci { file: PathBuf },
Dotenv { file: PathBuf },
}
impl Target {
pub fn kind_name(&self) -> &'static str {
match self {
Target::Compose { .. } => "compose",
Target::Actions { .. } => "GitHub Actions",
Target::Gitlab { .. } => "GitLab CI",
Target::Circleci { .. } => "CircleCI",
Target::Dotenv { .. } => "dotenv",
}
}
pub fn file(&self) -> &Path {
match self {
Target::Compose { file }
| Target::Actions { file }
| Target::Gitlab { file }
| Target::Circleci { file }
| Target::Dotenv { file } => file,
}
}
}
const COMPOSE_CANDIDATES: [&str; 4] = [
"compose.yaml",
"compose.yml",
"docker-compose.yml",
"docker-compose.yaml",
];
pub fn detect_in(dir: &Path) -> Option<Target> {
for name in COMPOSE_CANDIDATES {
let candidate = dir.join(name);
if candidate.is_file() {
return Some(Target::Compose { file: candidate });
}
}
let workflows = dir.join(".github/workflows");
if let Ok(entries) = std::fs::read_dir(&workflows) {
let mut files: Vec<PathBuf> = entries
.filter_map(Result::ok)
.map(|entry| entry.path())
.filter(|path| {
path.extension()
.map(|extension| extension == "yml" || extension == "yaml")
.unwrap_or(false)
})
.collect();
files.sort();
if let Some(file) = files.first() {
return Some(Target::Actions { file: file.clone() });
}
}
let gitlab = dir.join(".gitlab-ci.yml");
if gitlab.is_file() {
return Some(Target::Gitlab { file: gitlab });
}
let circleci = dir.join(".circleci/config.yml");
if circleci.is_file() {
return Some(Target::Circleci { file: circleci });
}
let dotenv = dir.join(".env");
if dotenv.is_file() {
return Some(Target::Dotenv { file: dotenv });
}
None
}
pub fn target_from_path(path: &Path) -> Option<Target> {
if path.is_file() {
return Some(Target::Compose {
file: path.to_path_buf(),
});
}
if path.is_dir() {
return detect_in(path);
}
None
}