use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct Configuration {
pub(crate) verbose: bool,
pub(crate) log_dir: Option<PathBuf>,
pub(crate) allow_uncontained: bool,
pub(crate) compile_agents: bool,
pub(crate) self_test: bool,
pub(crate) test_all_configs: bool,
pub(crate) debug_agent_stderr: bool,
}
impl Configuration {
pub fn new() -> Self {
Self {
verbose: true,
log_dir: None,
allow_uncontained: false,
compile_agents: true,
self_test: false,
test_all_configs: false,
debug_agent_stderr: false,
}
}
pub fn from_env() -> Self {
fn get_env_flag(var: &str, default: bool) -> bool {
match std::env::var(var) {
Ok(val) => val.eq_ignore_ascii_case("true"),
Err(_) => default,
}
}
let log_dir = std::env::var("EVAL_LOG_DIR")
.ok()
.map(PathBuf::from)
.filter(|p| p.is_dir());
Self {
verbose: get_env_flag("EVAL_VERBOSE", true),
log_dir,
allow_uncontained: get_env_flag("EVAL_ALLOW_UNCONTAINED", false),
compile_agents: get_env_flag("EVAL_COMPILE_AGENTS", true),
self_test: get_env_flag("EVAL_SELF_TEST", false),
test_all_configs: get_env_flag("EVAL_TEST_ALL_CONFIGS", false),
debug_agent_stderr: get_env_flag("EVAL_DEBUG_AGENT_STDERR", false),
}
}
pub fn with_verbose(mut self, value: bool) -> Self {
self.verbose = value;
self
}
pub fn with_log<P: AsRef<Path>>(mut self, path: P) -> Self {
let path = path.as_ref();
if !path.exists() {
std::fs::create_dir(&path)
.unwrap_or_else(|e| panic!("Could not create directory {}: {}", path.display(), e));
}
if !path.is_dir() {
panic!("Logging path must be a valid directory: {}", path.display());
}
for entry in std::fs::read_dir(path).unwrap_or_else(|e| {
panic!(
"Failed to read contents of directory {}: {}",
path.display(),
e
)
}) {
let entry = entry.unwrap();
let entry_path = entry.path();
if entry_path.is_symlink() {
std::fs::remove_file(&entry_path).unwrap_or_else(|e| {
panic!("Failed to remove simlink {}: {}", entry_path.display(), e);
});
} else if entry_path.is_dir() {
std::fs::remove_dir_all(&entry_path).unwrap_or_else(|e| {
panic!("Failed to remove directory {}: {}", entry_path.display(), e)
});
} else {
std::fs::remove_file(&entry_path).unwrap_or_else(|e| {
panic!("Failed to remove file {}: {}", entry_path.display(), e)
});
}
}
self.log_dir = Some(path.to_path_buf());
self
}
pub fn with_allow_uncontained(mut self, value: bool) -> Self {
self.allow_uncontained = value;
self
}
pub fn with_compile_agents(mut self, value: bool) -> Self {
self.compile_agents = value;
self
}
pub fn with_self_test(mut self, value: bool) -> Self {
self.self_test = value;
self
}
pub fn with_test_all_configs(mut self, value: bool) -> Self {
self.test_all_configs = value;
self
}
pub fn with_debug_agent_stderr(mut self, value: bool) -> Self {
self.debug_agent_stderr = value;
self
}
pub(crate) fn is_logging_enabled(&self) -> bool {
self.log_dir.is_some()
}
}
impl Default for Configuration {
fn default() -> Self {
Self::new()
}
}