use crate::{error::Result, utils::get_project_root};
use serde::Deserialize;
use std::{fs, path::PathBuf};
const CONFIG_NAMES: &[&str] = &["prdoc.toml", ".prdoc.toml"];
pub mod env {
pub const PRDOC_CONFIG: &str = "PRDOC_CONFIG";
pub const PRDOC_FOLDERS: &str = "PRDOC_FOLDERS";
}
#[derive(Debug, Deserialize)]
pub struct PRDocConfig {
pub(crate) schema: PathBuf,
pub prdoc_folders: Vec<PathBuf>,
pub(crate) output_dir: PathBuf,
pub(crate) template: PathBuf,
}
pub struct Config;
impl Config {
pub fn get_config_file(config_file: Option<PathBuf>) -> Result<PathBuf> {
let root = get_project_root().expect("prdoc should run in a repo");
if let Some(config) = config_file {
if PathBuf::from(&config).exists() {
log::debug!("Found config in {config:?}");
return Ok(config)
}
}
for name in CONFIG_NAMES {
let candidate = root.join(name);
if candidate.exists() {
log::debug!("Found config in {}", candidate.display());
return Ok(candidate)
}
}
log::warn!("Config not found");
Err(crate::error::PRdocLibError::MissingConfig)
}
pub fn get_default_config() -> PRDocConfig {
PRDocConfig::default()
}
pub fn load(config_opts: Option<PathBuf>) -> Result<PRDocConfig> {
let config_file = Self::get_config_file(config_opts)?;
log::debug!("Loading config from {config_file:?}");
let str = match fs::read_to_string(config_file.clone()) {
Ok(s) => s,
Err(_) => Err(crate::error::PRdocLibError::InvalidConfig(config_file.clone()))?,
};
match toml::from_str(str.as_str()) {
Ok(c) => Ok(c),
Err(_e) => Err(crate::error::PRdocLibError::InvalidConfig(config_file))?,
}
}
}
impl Default for PRDocConfig {
fn default() -> Self {
Self {
schema: "prdoc/schema_user.json".into(),
prdoc_folders: vec!["prdoc".into()],
output_dir: "prdoc".into(),
template: "template.prdoc".into(),
}
}
}
impl PRDocConfig {
pub fn schema_path(&self) -> PathBuf {
self.schema.clone()
}
}