fix: Handle '# [include]'. Update default config (#450)

This commit is contained in:
slowsage
2023-06-01 03:15:49 -04:00
committed by GitHub
parent 3f5eedb83d
commit 03436b7f8f
2 changed files with 26 additions and 22 deletions

View File

@@ -1,7 +1,7 @@
# Include any additional configuration file(s)
# [include] sections are processed in the order you write them
# Files in $CONFIG_DIR/topgrade/topgrade.d/ are automatically included at the beginning of this file
[include]
#[include]
#paths = ["/etc/topgrade.toml"]
[misc]

View File

@@ -198,8 +198,8 @@ pub enum Step {
#[derive(Deserialize, Default, Debug, Merge)]
#[serde(deny_unknown_fields)]
pub struct Include {
#[merge(strategy = merge::vec::append)]
paths: Vec<String>,
#[merge(strategy = crate::utils::merge_strategies::vec_prepend_opt)]
paths: Option<Vec<String>>,
}
#[derive(Deserialize, Default, Debug, Merge)]
@@ -611,7 +611,7 @@ impl ConfigFile {
// To parse [include] sections in the order as they are written,
// we split the file and parse each part as a separate file
let regex_match_include = Regex::new(r"\[include]").expect("Failed to compile regex");
let regex_match_include = Regex::new(r"^\s*\[include]").expect("Failed to compile regex");
let contents_split = regex_match_include.split_inclusive_left(contents_non_split.as_str());
for contents in contents_split {
@@ -622,25 +622,29 @@ impl ConfigFile {
if let Some(includes) = &config_file_include_only.include {
// Parses the [include] section present in the slice
for include in includes.paths.iter().rev() {
let include_path = shellexpand::tilde::<&str>(&include.as_ref()).into_owned();
let include_path = PathBuf::from(include_path);
let include_contents = match fs::read_to_string(&include_path) {
Ok(c) => c,
Err(e) => {
tracing::error!("Unable to read {}: {}", include_path.display(), e);
continue;
}
};
match toml::from_str::<Self>(&include_contents) {
Ok(include_parsed) => result.merge(include_parsed),
Err(e) => {
tracing::error!("Failed to deserialize {}: {}", include_path.display(), e);
continue;
}
};
if let Some(ref paths) = includes.paths {
for include in paths.iter().rev() {
let include_path = shellexpand::tilde::<&str>(&include.as_ref()).into_owned();
let include_path = PathBuf::from(include_path);
let include_contents = match fs::read_to_string(&include_path) {
Ok(c) => c,
Err(e) => {
tracing::error!("Unable to read {}: {}", include_path.display(), e);
continue;
}
};
match toml::from_str::<Self>(&include_contents) {
Ok(include_parsed) => result.merge(include_parsed),
Err(e) => {
tracing::error!("Failed to deserialize {}: {}", include_path.display(), e);
continue;
}
};
debug!("Configuration include found: {}", include_path.display());
debug!("Configuration include found: {}", include_path.display());
}
} else {
debug!("No include paths found in {}", config_path.display());
}
}