diff options
-rw-r--r-- | CHANGELOG.md | 7 | ||||
-rw-r--r-- | Cargo.lock | 48 | ||||
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | src/config.rs | 20 | ||||
-rw-r--r-- | src/main.rs | 7 |
5 files changed, 80 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c22351..17c176c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ Unreleased - Added support for configuration files - Added `toml` dependency in version `0.5.6` - Added `serde` dependency in version `1.0.114` + - Added `envy` dependency in version `0.4.1` + - Added `merge` dependency in version `0.1.0` 0.3.4 @@ -10,6 +12,11 @@ Unreleased - Changed default OTP format from `hex` to `base32` - Improved error reporting format and fidelity - Added `anyhow` dependency in version `1.0.32` +- Reworked environment variables: + - Added the `NITROCLI_MODEL` and `NITROCLI_VERBOSITY` variables that + set the defaults for the `--model` and `--verbose` options + - Changed the handling of the `NITROCLI_NO_CACHE` variable to check + the value of the variable instead of only the presence - Updated minimum required Rust version to `1.42.0` - Bumped `nitrokey` dependency to `0.7.1` - Bumped `proc-macro2` dependency to `1.0.19` @@ -16,6 +16,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" [[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] name = "base32" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -51,6 +57,15 @@ dependencies = [ ] [[package]] +name = "envy" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f938a4abd5b75fe3737902dbc2e79ca142cc1526827a9e40b829a086758531a9" +dependencies = [ + "serde", +] + +[[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -89,12 +104,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] +name = "merge" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9" +dependencies = [ + "merge_derive", + "num-traits", +] + +[[package]] +name = "merge_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "nitrocli" version = "0.3.4" dependencies = [ "anyhow", "base32", + "envy", "libc", + "merge", "nitrokey", "nitrokey-test", "nitrokey-test-state", @@ -143,6 +182,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a59b732ed6d5212424ed31ec9649f05652bcbc38f45f2292b27a6044e7098803" [[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[package]] name = "proc-macro-error" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -52,9 +52,15 @@ version = "1.0" [dependencies.base32] version = "0.4.0" +[dependencies.envy] +version = "0.4.1" + [dependencies.libc] version = "0.2" +[dependencies.merge] +version = "0.1" + [dependencies.nitrokey] version = "0.7.1" 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<args::DeviceModel>, /// 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<Self> { - 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<Option<Config>> { } } +fn load_env_config() -> anyhow::Result<Config> { + envy::prefixed("NITROCLI_") + .from_env() + .context("Failed to parse environment variables") +} + pub fn read_config_file(path: &path::Path) -> anyhow::Result<Config> { 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::<Vec<_>>(); let ctx = &mut RunCtx { stdout: &mut stdout, |