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 any additional configuration file(s)
# [include] sections are processed in the order you write them # [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 # Files in $CONFIG_DIR/topgrade/topgrade.d/ are automatically included at the beginning of this file
[include] #[include]
#paths = ["/etc/topgrade.toml"] #paths = ["/etc/topgrade.toml"]
[misc] [misc]

View File

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