mirror of
https://github.com/edera-dev/sprout.git
synced 2026-11-04 20:12:21 +00:00
fix(config): warn about unknown keys in the configuration
Keys that aren't part of the configuration were silently ignored, so a misspelled key like linux_initrd instead of linux-initrd, or menu_timeout instead of menu-timeout, quietly did nothing. Warn about each ignored key with its full path while loading the configuration. Also warn when an action or generator configures more than one kind, as only the first one found is used.
This commit is contained in:
1 parent
0d2eaa37c1
commit
f6064d8751
4 files changed
+83
-4
No files matched your search
Generated
+11
@@ -83,6 +83,7 @@ dependencies = [
|
||||
"hex",
|
||||
"jaarg",
|
||||
"log",
|
||||
"serde_ignored",
|
||||
"sha2",
|
||||
"toml",
|
||||
"uefi",
|
||||
@@ -237,6 +238,16 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_ignored"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.1.1"
|
||||
|
||||
@@ -41,6 +41,10 @@ version = "1.0.229"
|
||||
default-features = false
|
||||
features = ["alloc", "derive"]
|
||||
|
||||
[workspace.dependencies.serde_ignored]
|
||||
version = "0.1.14"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.sha2]
|
||||
version = "0.11.0"
|
||||
default-features = false
|
||||
|
||||
@@ -15,6 +15,7 @@ edera-sprout-bls.path = "../bls"
|
||||
edera-sprout-parsing.path = "../parsing"
|
||||
hex.workspace = true
|
||||
jaarg.workspace = true
|
||||
serde_ignored.workspace = true
|
||||
sha2.workspace = true
|
||||
toml.workspace = true
|
||||
log.workspace = true
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use crate::options::SproutOptions;
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec::Vec;
|
||||
use anyhow::{Context, Result, bail};
|
||||
use core::fmt::Display;
|
||||
use core::ops::Deref;
|
||||
use edera_sprout_config::{RootConfiguration, latest_version};
|
||||
use eficore::platform::tpm::PlatformTpm;
|
||||
use log::info;
|
||||
use log::{info, warn};
|
||||
use serde_ignored::Path;
|
||||
use toml::Value;
|
||||
use uefi::proto::device_path::LoadedImageDevicePath;
|
||||
|
||||
@@ -35,6 +39,59 @@ fn load_raw_config(options: &SproutOptions) -> Result<Vec<u8>> {
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
/// Format the configuration key `path` with dots, like "actions.linux.chainload.path".
|
||||
fn key_path(path: &Path) -> String {
|
||||
// Joins the `parent` path and the `key` with a dot, unless the parent is the root.
|
||||
fn join(parent: &Path, key: impl Display) -> String {
|
||||
match parent {
|
||||
Path::Root => key.to_string(),
|
||||
parent => format!("{}.{}", key_path(parent), key),
|
||||
}
|
||||
}
|
||||
|
||||
match path {
|
||||
Path::Root => String::new(),
|
||||
Path::Seq { parent, index } => join(parent, index),
|
||||
Path::Map { parent, key } => join(parent, key),
|
||||
// Optional values and wrapper types don't add a key of their own.
|
||||
Path::Some { parent }
|
||||
| Path::NewtypeStruct { parent }
|
||||
| Path::NewtypeVariant { parent } => key_path(parent),
|
||||
}
|
||||
}
|
||||
|
||||
/// Warn about each declaration in `config` that configures more than one kind.
|
||||
/// For example, an action with both chainload and print configured only runs chainload.
|
||||
fn warn_multiple_kinds(config: &RootConfiguration) {
|
||||
for (name, action) in &config.actions {
|
||||
let kinds = [
|
||||
action.chainload.is_some(),
|
||||
action.print.is_some(),
|
||||
action.edera.is_some(),
|
||||
];
|
||||
if kinds.iter().filter(|kind| **kind).count() > 1 {
|
||||
warn!(
|
||||
"action {} configures more than one action, only one is used",
|
||||
name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (name, generator) in &config.generators {
|
||||
let kinds = [
|
||||
generator.matrix.is_some(),
|
||||
generator.bls.is_some(),
|
||||
generator.list.is_some(),
|
||||
];
|
||||
if kinds.iter().filter(|kind| **kind).count() > 1 {
|
||||
warn!(
|
||||
"generator {} configures more than one generator, only one is used",
|
||||
name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads the [RootConfiguration] for Sprout.
|
||||
pub fn load(options: &SproutOptions) -> Result<RootConfiguration> {
|
||||
// Load the raw configuration from the sprout config file.
|
||||
@@ -59,9 +116,15 @@ pub fn load(options: &SproutOptions) -> Result<RootConfiguration> {
|
||||
}
|
||||
|
||||
// If the version is supported, parse the full configuration.
|
||||
let config: RootConfiguration = value
|
||||
.try_into()
|
||||
.context("unable to parse sprout.toml file")?;
|
||||
// Keys that aren't part of the configuration, such as misspelled keys, are ignored.
|
||||
// Warn about each one, as the configuration may not do what was intended.
|
||||
let config: RootConfiguration = serde_ignored::deserialize(value, |path| {
|
||||
warn!("ignoring unknown configuration key: {}", key_path(&path));
|
||||
})
|
||||
.context("unable to parse sprout.toml file")?;
|
||||
|
||||
// Warn about declarations that configure more than one kind, as only one is used.
|
||||
warn_multiple_kinds(&config);
|
||||
|
||||
// Return the parsed configuration.
|
||||
Ok(config)
|
||||
|
||||
Reference in new issue
Block a user