From 4ee8422ff9b361542d9e7839e5027065b9a42c03 Mon Sep 17 00:00:00 2001 From: jake goldsborough Date: Sat, 8 Jun 2024 17:06:52 -0700 Subject: [PATCH 1/5] adding global variable to enable symlinks by default if type not specified --- src/config.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/config.rs b/src/config.rs index 9ccc777..879a3af 100644 --- a/src/config.rs +++ b/src/config.rs @@ -110,6 +110,7 @@ struct GlobalConfig { helpers: Helpers, #[serde(flatten)] packages: BTreeMap, + variables: Option, } type IncludedConfig = BTreeMap; @@ -211,6 +212,7 @@ pub fn save_dummy_config( #[cfg(feature = "scripting")] helpers: Helpers::new(), packages, + variables: None, }; debug!("Saving global config..."); // Assume default args so all parents are the same @@ -373,6 +375,36 @@ fn merge_configuration_files( output.files = first_package.files; output.variables = first_package.variables; + // Defaults package target type to symlink if + // enable_symlink_by_default = true and + // package is not explicitly set as template + if let Some(variables) = global.variables { + if let Some(enable_symlink_by_default) = + variables + .get("enable_symlink_by_default") + .and_then(toml::Value::as_bool) { + if enable_symlink_by_default { + output.files = output + .files + .into_iter() + .map(|(name, target)| -> Result<_, anyhow::Error> { + let t: FileTarget; + + match target { + FileTarget::Automatic(target) => { + t = FileTarget::Symbolic( + SymbolicTarget::from(target) + ); + }, + _ => t = target, + } + Ok((name, t)) + }) + .collect::>()?; + } + } + } + // Add local.toml's patches output.files.extend(local.files); recursive_extend_map(&mut output.variables, local.variables); @@ -632,4 +664,64 @@ mod test { ) .unwrap_err(); } + + #[test] + fn enable_symlink_by_default() { + let global: GlobalConfig = toml::from_str( + r#" + [variables] + enable_symlink_by_default = true + + [cat] + depends = [] + + [cat.files] + cat = '~/.QuarticCat' + + [derby] + depends = [] + + [derby.files] + derby = { target = '~/.DerbyLantern', type = 'template' } + "#, + ) + .unwrap(); + + let local: LocalConfig = toml::from_str( + r#" + packages = ['cat', 'derby'] + "#, + ) + .unwrap(); + + let merged_config = + merge_configuration_files(global, local, None); + + let config = merged_config.unwrap(); + + let cat = config + .files + .get(&PathBuf::from("cat")) + .unwrap(); + + let derby = config + .files + .get(&PathBuf::from("derby")) + .unwrap(); + + assert_eq!( + cat, + &FileTarget::Symbolic(PathBuf::from("~/.QuarticCat").into()) + ); + + assert_ne!( + derby, + &FileTarget::Symbolic(PathBuf::from("~/.DerbyLantern").into()) + ); + + assert_eq!( + derby, + &FileTarget::ComplexTemplate(PathBuf::from("~/.DerbyLantern").into()) + ); + } } From 18a83f40d65f0d0f9c0e725efdaeb44eaf769724 Mon Sep 17 00:00:00 2001 From: jake goldsborough Date: Sat, 15 Jun 2024 16:48:00 -0700 Subject: [PATCH 2/5] adding global settings and a default_target_type property based on this property, any package files that don't explicity set a target type will be transformed. also adds a test for each option. --- src/config.rs | 217 ++++++++++++++++++++++++++++++++------ src/handlebars_helpers.rs | 4 + 2 files changed, 188 insertions(+), 33 deletions(-) diff --git a/src/config.rs b/src/config.rs index 879a3af..5cded78 100644 --- a/src/config.rs +++ b/src/config.rs @@ -76,6 +76,21 @@ pub type Variables = toml::value::Table; #[cfg(feature = "scripting")] pub type Helpers = BTreeMap; +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum DefaultTargetType { + Symbolic, + Template, + #[default] + Automatic, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct Settings { + #[serde(default)] + default_target_type: DefaultTargetType, +} + #[derive(Debug, Clone)] pub struct Configuration { pub files: Files, @@ -90,6 +105,8 @@ pub struct Configuration { /// turned into a list of all the files inside the structure that /// are readable. pub recurse: bool, + + pub settings: Settings, } #[derive(Debug, Deserialize, Serialize, Default)] @@ -110,7 +127,8 @@ struct GlobalConfig { helpers: Helpers, #[serde(flatten)] packages: BTreeMap, - variables: Option, + #[serde(default)] + settings: Settings, } type IncludedConfig = BTreeMap; @@ -212,7 +230,7 @@ pub fn save_dummy_config( #[cfg(feature = "scripting")] helpers: Helpers::new(), packages, - variables: None, + settings: Settings::default(), }; debug!("Saving global config..."); // Assume default args so all parents are the same @@ -332,6 +350,7 @@ fn merge_configuration_files( variables: Variables::default(), packages: packages_map, recurse: true, + settings: Settings::default(), }; // Merge all the packages @@ -375,34 +394,10 @@ fn merge_configuration_files( output.files = first_package.files; output.variables = first_package.variables; - // Defaults package target type to symlink if - // enable_symlink_by_default = true and - // package is not explicitly set as template - if let Some(variables) = global.variables { - if let Some(enable_symlink_by_default) = - variables - .get("enable_symlink_by_default") - .and_then(toml::Value::as_bool) { - if enable_symlink_by_default { - output.files = output - .files - .into_iter() - .map(|(name, target)| -> Result<_, anyhow::Error> { - let t: FileTarget; - - match target { - FileTarget::Automatic(target) => { - t = FileTarget::Symbolic( - SymbolicTarget::from(target) - ); - }, - _ => t = target, - } - Ok((name, t)) - }) - .collect::>()?; - } - } + if let DefaultTargetType::Symbolic = global.settings.default_target_type { + output.files = transform_file_targets(output.files, FileTargetTransform::Symbolic); + } else if let DefaultTargetType::Template = global.settings.default_target_type { + output.files = transform_file_targets(output.files, FileTargetTransform::Template); } // Add local.toml's patches @@ -594,6 +589,34 @@ impl UnixUser { } } +enum FileTargetTransform { + Symbolic, + Template, +} + +fn transform_file_targets( + files: Files, + transform_target: FileTargetTransform, +) -> Files { + files + .into_iter() + .map(|(name, target)| -> _ { + let t = match target { + FileTarget::Automatic(target) => match transform_target { + FileTargetTransform::Symbolic => { + FileTarget::Symbolic(SymbolicTarget::from(target)) + }, + FileTargetTransform::Template => { + FileTarget::ComplexTemplate(TemplateTarget::from(target)) + } + }, + _ => target, + }; + (name, t) + }) + .collect::() +} + #[cfg(test)] mod test { use super::*; @@ -666,11 +689,11 @@ mod test { } #[test] - fn enable_symlink_by_default() { + fn settting_default_target_type_symbolic() { let global: GlobalConfig = toml::from_str( r#" - [variables] - enable_symlink_by_default = true + [settings] + default_target_type = "symbolic" [cat] depends = [] @@ -724,4 +747,132 @@ mod test { &FileTarget::ComplexTemplate(PathBuf::from("~/.DerbyLantern").into()) ); } + + #[test] + fn setting_default_target_type_template() { + let global: GlobalConfig = toml::from_str( + r#" + [settings] + default_target_type = "template" + + [cat] + depends = [] + + [cat.files] + cat = '~/.QuarticCat' + + [derby] + depends = [] + + [derby.files] + derby = { target = '~/.DerbyLantern', type = 'symbolic' } + "#, + ) + .unwrap(); + + let local: LocalConfig = toml::from_str( + r#" + packages = ['cat', 'derby'] + "#, + ) + .unwrap(); + + let merged_config = + merge_configuration_files(global, local, None); + + let config = merged_config.unwrap(); + + let cat = config + .files + .get(&PathBuf::from("cat")) + .unwrap(); + + let derby = config + .files + .get(&PathBuf::from("derby")) + .unwrap(); + + assert_eq!( + cat, + &FileTarget::ComplexTemplate(PathBuf::from("~/.QuarticCat").into()) + ); + + assert_ne!( + derby, + &FileTarget::ComplexTemplate(PathBuf::from("~/.DerbyLantern").into()) + ); + + assert_eq!( + derby, + &FileTarget::Symbolic(PathBuf::from("~/.DerbyLantern").into()) + ); + } + + #[test] + fn setting_default_target_type_automatic() { + let global: GlobalConfig = toml::from_str( + r#" + [cat] + depends = [] + + [cat.files] + cat = '~/.QuarticCat' + + [derby] + depends = [] + + [derby.files] + derby = { target = '~/.DerbyLantern', type = 'template' } + + [sliver] + depends = [] + + [sliver.files] + sliver = { target = '~/.SliverBodacious', type = 'symbolic' } + "#, + ) + .unwrap(); + + let local: LocalConfig = toml::from_str( + r#" + packages = ['cat', 'derby', 'sliver'] + "#, + ) + .unwrap(); + + let merged_config = + merge_configuration_files(global, local, None); + + let config = merged_config.unwrap(); + + let cat = config + .files + .get(&PathBuf::from("cat")) + .unwrap(); + + let derby = config + .files + .get(&PathBuf::from("derby")) + .unwrap(); + + let sliver = config + .files + .get(&PathBuf::from("sliver")) + .unwrap(); + + assert_eq!( + cat, + &FileTarget::Automatic(PathBuf::from("~/.QuarticCat").into()) + ); + + assert_eq!( + derby, + &FileTarget::ComplexTemplate(PathBuf::from("~/.DerbyLantern").into()) + ); + + assert_eq!( + sliver, + &FileTarget::Symbolic(PathBuf::from("~/.SliverBodacious").into()) + ); + } } diff --git a/src/handlebars_helpers.rs b/src/handlebars_helpers.rs index 38af55e..beda2dd 100644 --- a/src/handlebars_helpers.rs +++ b/src/handlebars_helpers.rs @@ -351,6 +351,8 @@ fn add_dotter_variable( #[cfg(test)] mod test { + use crate::config::Settings; + use super::*; #[test] @@ -362,6 +364,7 @@ mod test { helpers: Helpers::new(), packages: maplit::btreemap! { "default".into() => true, "disabled".into() => false }, recurse: true, + settings: Settings::default(), }; let handlebars = create_new_handlebars(&mut config).unwrap(); @@ -388,6 +391,7 @@ mod test { helpers: Helpers::new(), packages: BTreeMap::new(), recurse: true, + settings: Settings::default(), }; let handlebars = create_new_handlebars(&mut config).unwrap(); From 1c8bebdb2b7712d813426fd2d7744a53d6b9ebab Mon Sep 17 00:00:00 2001 From: jake goldsborough Date: Mon, 17 Jun 2024 12:58:06 -0700 Subject: [PATCH 3/5] reworking how the default_target_type transforms are handled --- src/config.rs | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5cded78..da8d5fd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -394,10 +394,18 @@ fn merge_configuration_files( output.files = first_package.files; output.variables = first_package.variables; - if let DefaultTargetType::Symbolic = global.settings.default_target_type { - output.files = transform_file_targets(output.files, FileTargetTransform::Symbolic); - } else if let DefaultTargetType::Template = global.settings.default_target_type { - output.files = transform_file_targets(output.files, FileTargetTransform::Template); + for value in output.files.values_mut() { + if let FileTarget::Automatic(target) = value { + *value = match global.settings.default_target_type { + DefaultTargetType::Symbolic => { + FileTarget::Symbolic(SymbolicTarget::from(target.clone())) + } + DefaultTargetType::Template => { + FileTarget::ComplexTemplate(TemplateTarget::from(target.clone())) + } + _ => continue, + }; + } } // Add local.toml's patches @@ -589,34 +597,6 @@ impl UnixUser { } } -enum FileTargetTransform { - Symbolic, - Template, -} - -fn transform_file_targets( - files: Files, - transform_target: FileTargetTransform, -) -> Files { - files - .into_iter() - .map(|(name, target)| -> _ { - let t = match target { - FileTarget::Automatic(target) => match transform_target { - FileTargetTransform::Symbolic => { - FileTarget::Symbolic(SymbolicTarget::from(target)) - }, - FileTargetTransform::Template => { - FileTarget::ComplexTemplate(TemplateTarget::from(target)) - } - }, - _ => target, - }; - (name, t) - }) - .collect::() -} - #[cfg(test)] mod test { use super::*; From be0ba6d7a061cba1c9be01310c2ae6da1e66ebc5 Mon Sep 17 00:00:00 2001 From: jake goldsborough Date: Mon, 17 Jun 2024 12:58:21 -0700 Subject: [PATCH 4/5] running cargo fmt --- src/config.rs | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/src/config.rs b/src/config.rs index da8d5fd..99447a9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -697,20 +697,13 @@ mod test { ) .unwrap(); - let merged_config = - merge_configuration_files(global, local, None); + let merged_config = merge_configuration_files(global, local, None); let config = merged_config.unwrap(); - let cat = config - .files - .get(&PathBuf::from("cat")) - .unwrap(); + let cat = config.files.get(&PathBuf::from("cat")).unwrap(); - let derby = config - .files - .get(&PathBuf::from("derby")) - .unwrap(); + let derby = config.files.get(&PathBuf::from("derby")).unwrap(); assert_eq!( cat, @@ -757,20 +750,13 @@ mod test { ) .unwrap(); - let merged_config = - merge_configuration_files(global, local, None); + let merged_config = merge_configuration_files(global, local, None); let config = merged_config.unwrap(); - let cat = config - .files - .get(&PathBuf::from("cat")) - .unwrap(); + let cat = config.files.get(&PathBuf::from("cat")).unwrap(); - let derby = config - .files - .get(&PathBuf::from("derby")) - .unwrap(); + let derby = config.files.get(&PathBuf::from("derby")).unwrap(); assert_eq!( cat, @@ -820,25 +806,15 @@ mod test { ) .unwrap(); - let merged_config = - merge_configuration_files(global, local, None); + let merged_config = merge_configuration_files(global, local, None); let config = merged_config.unwrap(); - let cat = config - .files - .get(&PathBuf::from("cat")) - .unwrap(); + let cat = config.files.get(&PathBuf::from("cat")).unwrap(); - let derby = config - .files - .get(&PathBuf::from("derby")) - .unwrap(); + let derby = config.files.get(&PathBuf::from("derby")).unwrap(); - let sliver = config - .files - .get(&PathBuf::from("sliver")) - .unwrap(); + let sliver = config.files.get(&PathBuf::from("sliver")).unwrap(); assert_eq!( cat, From 2b9280255d4fa02c9ad60652e1dc3a032bfc8237 Mon Sep 17 00:00:00 2001 From: jake goldsborough Date: Tue, 18 Jun 2024 07:59:02 -0700 Subject: [PATCH 5/5] adding temp allow(dead_code) for new, unused field --- src/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.rs b/src/config.rs index 99447a9..538f41e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -106,6 +106,7 @@ pub struct Configuration { /// are readable. pub recurse: bool, + #[allow(dead_code)] pub settings: Settings, }