use anyhow::Result;
use maplit::hashmap;
use std::{collections::HashMap, path::Path, process::Command};
use shrub_rs::models::{project::EvgProject, task::EvgTask, variant::BuildVariant};
const REQUIRED_PREFIX: &str = "-required";
pub trait EvgConfigService: Sync + Send {
fn get_build_variant_map(&self) -> HashMap<String, &BuildVariant>;
fn get_task_def_map(&self) -> HashMap<String, EvgTask>;
fn sort_build_variants_by_required(&self) -> Vec<String>;
fn get_module_dir(&self, module_name: &str) -> Option<String>;
}
pub struct EvgProjectConfig {
evg_project: EvgProject,
}
impl EvgProjectConfig {
pub fn new(evg_project_location: &Path) -> Result<Self> {
let evg_project = get_project_config(evg_project_location)?;
Ok(Self { evg_project })
}
}
impl EvgConfigService for EvgProjectConfig {
fn get_build_variant_map(&self) -> HashMap<String, &BuildVariant> {
self.evg_project.build_variant_map()
}
fn get_task_def_map(&self) -> HashMap<String, EvgTask> {
let mut task_map = hashmap! {};
for (k, v) in self.evg_project.task_def_map() {
task_map.insert(k, v.clone());
}
task_map
}
fn sort_build_variants_by_required(&self) -> Vec<String> {
let build_variant_map = self.get_build_variant_map();
let mut build_variants: Vec<String> = build_variant_map
.keys()
.into_iter()
.filter_map(|bv| {
if bv.ends_with(REQUIRED_PREFIX) {
Some(bv.to_string())
} else {
None
}
})
.collect();
build_variants.extend::<Vec<String>>(
build_variant_map
.keys()
.into_iter()
.filter_map(|bv| {
if !bv.ends_with(REQUIRED_PREFIX) {
Some(bv.to_string())
} else {
None
}
})
.collect(),
);
build_variants
}
fn get_module_dir(&self, module_name: &str) -> Option<String> {
if let Some(modules) = &self.evg_project.modules {
for module in modules {
if module.name == module_name {
return Some(format!("{}/{}", &module.prefix, module_name));
}
}
}
None
}
}
fn get_project_config(location: &Path) -> Result<EvgProject> {
let evg_config_yaml = Command::new("evergreen")
.args(&["evaluate", location.to_str().unwrap()])
.output()?;
Ok(EvgProject::from_yaml_str(std::str::from_utf8(&evg_config_yaml.stdout)?).unwrap())
}