Files
radicle-native-ci/src/config.rs
T
2024-01-10 17:38:05 +02:00

66 lines
2.0 KiB
Rust

use std::path::{Path, PathBuf};
use log::{debug, error};
use serde::Deserialize;
use crate::logfile::{LogError, LogFile};
const DEFAULT_TIMEOUT: usize = 3600;
/// Configuration file for `radicle-native-ci`.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
/// Directory where per-run directories are stored. Each run gets
/// its own dedicated subdirectory.
pub state: PathBuf,
/// File where native CI should write a log.
pub log: PathBuf,
/// Optional maximum duration of a CI run.
pub timeout: Option<usize>,
}
impl Config {
pub fn load_via_env() -> Result<Self, ConfigError> {
const ENV: &str = "RADICLE_NATIVE_CI";
let filename = std::env::var(ENV).map_err(|e| ConfigError::GetEnv(ENV, e))?;
let filename = Path::new(&filename);
let config = Config::read(filename)?;
debug!("configuration from {}: {:#?}", filename.display(), config);
Ok(config)
}
pub fn open_log(&self) -> Result<LogFile, ConfigError> {
Ok(LogFile::open(&self.log)?)
}
/// Read configuration specification from a file.
pub fn read(filename: &Path) -> Result<Self, ConfigError> {
let file = std::fs::File::open(filename)
.map_err(|e| ConfigError::ReadConfig(filename.into(), e))?;
let mut config: Self = serde_yaml::from_reader(&file)
.map_err(|e| ConfigError::ParseConfig(filename.into(), e))?;
if config.timeout.is_none() {
config.timeout = Some(DEFAULT_TIMEOUT);
}
Ok(config)
}
}
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("failed to read configuration file {0}")]
ReadConfig(PathBuf, #[source] std::io::Error),
#[error("failed to parse configuration file as YAML: {0}")]
ParseConfig(PathBuf, #[source] serde_yaml::Error),
#[error("failed to get environment variable {0}")]
GetEnv(&'static str, #[source] std::env::VarError),
#[error(transparent)]
Log(#[from] LogError),
}