From b4b7605e1f947ef0c58d94354c10fd74fd010a53 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 23 Jan 2020 14:04:42 +0100 Subject: Use envy to parse environment variables for Config This patch uses the envy crate to parse the environment. A variable NITROCLI_KEY can be used to overwrite the configuration for *key*. This has the side effect that the NITROCLI_NO_CACHE variable is evaluated as a boolean variable (instead of only checking whether it is set). We also accept two new variables, NITROCLI_MODEL and NITROCLI_VERBOSITY. --- src/config.rs | 20 ++++++++++++++++++-- src/main.rs | 7 +------ 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/config.rs b/src/config.rs index 850d217..2e8f3ba 100644 --- a/src/config.rs +++ b/src/config.rs @@ -26,21 +26,31 @@ use anyhow::Context as _; /// The configuration for nitrocli, usually read from configuration /// files and environment variables. -#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize)] +#[derive(Clone, Copy, Debug, Default, PartialEq, merge::Merge, serde::Deserialize)] pub struct Config { /// The model to connect to. pub model: Option, /// Whether to bypass the cache for all secrets or not. + #[merge(strategy = merge::bool::overwrite_false)] #[serde(default)] pub no_cache: bool, /// The log level. + #[merge(strategy = merge::num::overwrite_zero)] #[serde(default)] pub verbosity: u8, } impl Config { pub fn load() -> anyhow::Result { - load_user_config().map(|o| o.unwrap_or_default()) + use merge::Merge as _; + + let mut config = Config::default(); + if let Some(user_config) = load_user_config()? { + config.merge(user_config); + } + config.merge(load_env_config()?); + + Ok(config) } pub fn update(&mut self, args: &args::Args) { @@ -62,6 +72,12 @@ fn load_user_config() -> anyhow::Result> { } } +fn load_env_config() -> anyhow::Result { + envy::prefixed("NITROCLI_") + .from_env() + .context("Failed to parse environment variables") +} + pub fn read_config_file(path: &path::Path) -> anyhow::Result { let s = fs::read_to_string(path) .with_context(|| format!("Failed to read configuration file '{}'", path.display()))?; diff --git a/src/main.rs b/src/main.rs index 3535a91..b53358e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,7 +84,6 @@ const NITROCLI_USER_PIN: &str = "NITROCLI_USER_PIN"; const NITROCLI_NEW_ADMIN_PIN: &str = "NITROCLI_NEW_ADMIN_PIN"; const NITROCLI_NEW_USER_PIN: &str = "NITROCLI_NEW_USER_PIN"; const NITROCLI_PASSWORD: &str = "NITROCLI_PASSWORD"; -const NITROCLI_NO_CACHE: &str = "NITROCLI_NO_CACHE"; trait Stdio { fn stdio(&mut self) -> (&mut dyn io::Write, &mut dyn io::Write); @@ -206,11 +205,7 @@ fn main() { let mut stderr = io::stderr(); let rc = match config::Config::load() { - Ok(mut config) => { - if env::var_os(NITROCLI_NO_CACHE).is_some() { - config.no_cache = true; - } - + Ok(config) => { let args = env::args().collect::>(); let ctx = &mut RunCtx { stdout: &mut stdout, -- cgit v1.2.1