use crate::error::Result;
use crate::platforms::github::models::GitHubWorkflow;
use crate::platforms::gitlab::models::GitLabCI;
use crate::traits::Preset;
use std::fs;
use std::path::Path;
pub struct PresetDetector {
presets: Vec<Box<dyn Preset>>,
}
impl PresetDetector {
pub fn new() -> Self {
Self {
presets: vec![
],
}
}
pub fn add_preset(&mut self, preset: Box<dyn Preset>) {
self.presets.push(preset);
}
pub fn detect_github(&self, workflow: &GitHubWorkflow) -> Vec<&str> {
self.presets
.iter()
.filter(|p| p.matches_github(workflow))
.map(|p| p.name())
.collect()
}
pub fn detect_gitlab(&self, config: &GitLabCI) -> Vec<&str> {
self.presets
.iter()
.filter(|p| p.matches_gitlab(config))
.map(|p| p.name())
.collect()
}
pub fn detect_from_file(&self, path: &Path) -> Result<Vec<&str>> {
let content = fs::read_to_string(path)?;
if path.to_string_lossy().contains(".github/workflows") {
let workflow: GitHubWorkflow = serde_yaml::from_str(&content)?;
Ok(self.detect_github(&workflow))
} else if path
.file_name()
.map(|n| n == ".gitlab-ci.yml")
.unwrap_or(false)
{
let config: GitLabCI = serde_yaml::from_str(&content)?;
Ok(self.detect_gitlab(&config))
} else {
Ok(vec![])
}
}
pub fn list_presets(&self) -> Vec<(&str, &str)> {
self.presets
.iter()
.map(|p| (p.name(), p.description()))
.collect()
}
}
impl Default for PresetDetector {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detector_creation() {
let detector = PresetDetector::new();
assert_eq!(detector.presets.len(), 0);
}
}