Skip to content

Commit

Permalink
feat!: [torrust#938] add mandatory config options
Browse files Browse the repository at this point in the history
Some configuration options are mandatory. The tracker will panic if the user doesn't provide an explicit value for them from one of the configuration sources: TOML or ENV VARS.

The mandatory options are:

```toml
[metadata]
schema_version = "2.0.0"

[logging]
threshold = "info"

[core]
private = false
listed = false
```
  • Loading branch information
josecelano committed Aug 2, 2024
1 parent f95b16a commit 358c743
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ pub enum Error {

#[error("Unsupported configuration version: {version}")]
UnsupportedVersion { version: Version },

#[error("Missing mandatory option: {path}")]
MissingMandatoryOption { path: String },

#[error("Missing figment metadata for mandatory option: {path}")]
MissingMandatoryOptionMetadata { path: String },
}

impl From<figment::Error> for Error {
Expand Down
45 changes: 45 additions & 0 deletions packages/configuration/src/v2_0_0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ impl Configuration {
.merge(Env::prefixed(CONFIG_OVERRIDE_PREFIX).split(CONFIG_OVERRIDE_SEPARATOR))
};

Self::check_mandatory_options(&figment)?;

let config: Configuration = figment.extract()?;

if config.metadata.schema_version != Version::new(VERSION_2_0_0) {
Expand All @@ -343,6 +345,49 @@ impl Configuration {
Ok(config)
}

/// Some configuration options are mandatory. The tracker will panic if
/// the user doesn't provide an explicit value for them from one of the
/// configuration sources: TOML or ENV VARS.
///
/// # Errors
///
/// Will return an error if a mandatory configuration option is only
/// obtained by default value (code), meaning the user hasn't overridden it.
fn check_mandatory_options(figment: &Figment) -> Result<(), Error> {
let mandatory_options = ["metadata.schema_version", "logging.threshold", "core.private", "core.listed"];

for mandatory_option in mandatory_options {
let app = figment
.find_value(mandatory_option)
.map_err(|_err| Error::MissingMandatoryOption {
path: mandatory_option.to_owned(),
})?;

let metadata = figment
.get_metadata(app.tag())
.ok_or_else(|| Error::MissingMandatoryOptionMetadata {
path: mandatory_option.to_owned(),
})?;

match &metadata.source {
Some(source) => {
if let figment::Source::Code(_) = source {
return Err(Error::MissingMandatoryOption {
path: mandatory_option.to_owned(),
});
};
}
None => {
return Err(Error::MissingMandatoryOption {
path: mandatory_option.to_owned(),
})
}
}
}

Ok(())
}

/// Saves the configuration to the configuration file.
///
/// # Errors
Expand Down

0 comments on commit 358c743

Please sign in to comment.