pub mod circleci;
pub mod github;
pub mod gitlab;
use crate::error::{PipecheckError, Result};
use crate::models::{Pipeline, Provider};
use serde_yaml::Value;
pub fn detect_provider(content: &str) -> Result<Provider> {
let yaml: Value = match serde_yaml::from_str(content) {
Ok(v) => v,
Err(_) => {
return Err(PipecheckError::UnknownProvider(
"Not a valid YAML file".to_string(),
))
}
};
if let Some(map) = yaml.as_mapping() {
if map.contains_key("on") && (map.contains_key("jobs") || map.contains_key("runs-on")) {
return Ok(Provider::GitHubActions);
}
if (map.contains_key("stages")
|| map.contains_key("image")
|| map.contains_key("before_script"))
&& !map.contains_key("on")
&& !map.contains_key("workflows")
{
return Ok(Provider::GitLabCI);
}
if map.contains_key("version")
&& (map.contains_key("workflows") || map.contains_key("jobs"))
&& !map.contains_key("on")
{
return Ok(Provider::CircleCI);
}
}
if content.contains("on:") && (content.contains("jobs:") || content.contains("runs-on:")) {
Ok(Provider::GitHubActions)
} else if content.contains("stages:") && content.contains("script:") {
Ok(Provider::GitLabCI)
} else if content.contains("version:")
&& (content.contains("workflows:") || content.contains("jobs:"))
{
Ok(Provider::CircleCI)
} else {
Err(PipecheckError::UnknownProvider(
"Could not detect CI/CD provider".to_string(),
))
}
}
pub fn parse(content: &str, provider: Provider) -> Result<Pipeline> {
match provider {
Provider::GitHubActions => github::parse(content),
Provider::GitLabCI => gitlab::parse(content),
Provider::CircleCI => circleci::parse(content),
}
}