use serde::Deserialize;
use std::{
path::{Path, PathBuf},
time::Duration,
};
use crate::{errors, executor::suite};
#[derive(Debug, Deserialize)]
pub struct Config {
pub ver: String,
pub tests: Vec<SuiteConfig>,
}
#[derive(Debug, Deserialize)]
pub struct SuiteConfig {
pub name: String,
pub paths: Vec<String>,
pub cmd: String,
pub expect_dir: Option<PathBuf>,
pub timeout: Option<u64>,
}
impl Config {
pub fn from_path(conf_dir: &Path) -> Result<Self, errors::RuntError> {
let conf_path = conf_dir.join("runt.toml");
let contents = &std::fs::read_to_string(&conf_path).map_err(|_| {
errors::RuntError(format!(
"{} is missing. Runt expects a directory with a runt.toml file.",
conf_path.to_str().unwrap()
))
})?;
let conf: Config = toml::from_str(contents).map_err(|err| {
errors::RuntError(format!(
"Failed to parse {}: {}",
conf_path.to_str().unwrap(),
err
))
})?;
if env!("CARGO_PKG_VERSION") != conf.ver {
return Err(errors::RuntError(format!("Runt version mismatch. Configuration requires: {}, tool version: {}.\nRun `cargo install runt` to get the latest version of runt.", conf.ver, env!("CARGO_PKG_VERSION"))));
}
Ok(conf)
}
}
impl From<SuiteConfig> for suite::Suite {
fn from(conf: SuiteConfig) -> Self {
let all_paths = conf
.paths
.into_iter()
.map(|pattern| glob::glob(&pattern))
.collect::<Result<Vec<_>, glob::PatternError>>()
.expect("Glob pattern error")
.into_iter()
.flat_map(|paths| paths.collect::<Vec<_>>())
.collect::<Result<Vec<_>, _>>()
.expect("Failed to read globbed path");
suite::Suite {
paths: all_paths,
config: suite::Config {
name: conf.name,
cmd: conf.cmd,
expect_dir: conf.expect_dir,
timeout: Duration::from_secs(conf.timeout.unwrap_or(1200)),
},
}
}
}