From 12101b064bd8b2b9b47362c1833cc27ba4909fa8 Mon Sep 17 00:00:00 2001 From: InioX Date: Sun, 30 Jun 2024 00:01:08 +0200 Subject: [PATCH] feat: fix relative paths for templates, format `compare_to` (#83) --- example/config.toml | 6 +++--- src/main.rs | 3 ++- src/util/config.rs | 14 +++++++------- src/util/template.rs | 44 +++++++++++++++++++++++++++++++++++-------- src/util/variables.rs | 2 +- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/example/config.toml b/example/config.toml index 545a7bf..3a8a1d8 100644 --- a/example/config.toml +++ b/example/config.toml @@ -12,8 +12,8 @@ swww_options = [ test = "aaaa" [templates.name1] -input_path = "example/colors.whatever-extension" -output_path = "example/a/colors-generated.whatever-extension" +input_path = "./colors.whatever-extension" +output_path = "./a/colors-generated.whatever-extension" colors_to_compare = [ { name = "black", color = "#000000" }, { name = "red", color = "#ff0000" }, @@ -29,7 +29,7 @@ colors_to_compare = [ { name = "fuchsia", color = "#ff00ff" }, { name = "purple", color = "#800080" }, ] -compare_to = "#aefbd5" +compare_to = "{{colors.primary.default.hex}}" hook = 'echo "source color {{colors.source_color.default.hex}}, source image {{image}}, compared color {{compared_color}}"' [config.custom_colors] diff --git a/src/main.rs b/src/main.rs index 332af75..67e1ef5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,7 +53,7 @@ fn main() -> Result<(), Report> { setup_logging(log_level)?; - let config: ConfigFile = ConfigFile::read(&args)?; + let (config, config_path) = ConfigFile::read(&args)?; if config.config.version_check == Some(true) { check_version(); @@ -142,6 +142,7 @@ fn main() -> Result<(), Report> { &default_scheme, &config.config.custom_keywords, &args.prefix, + config_path )?; if config.config.reload_apps == Some(true) { diff --git a/src/util/config.rs b/src/util/config.rs index 3fe1e16..8085c22 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -84,9 +84,9 @@ const DEFAULT_CONFIG: &str = r#" "#; impl ConfigFile { - pub fn read(args: &Cli) -> Result { + pub fn read(args: &Cli) -> Result<(ConfigFile, Option), Report> { match &args.config { - Some(config_file) => Ok(Self::read_from_custom_path(config_file)?), + Some(config_file) => Ok((Self::read_from_custom_path(config_file)?, Some(config_file.to_path_buf()))), None => Ok(Self::read_from_proj_path()?), } } @@ -105,22 +105,22 @@ impl ConfigFile { } } - fn read_from_proj_path() -> Result { + fn read_from_proj_path() -> Result<(ConfigFile, Option), Report> { if let Some(proj_dirs) = ProjectDirs::from("com", "InioX", "matugen") { let proj_dir = proj_dirs.config_dir(); let config_file = PathBuf::from(proj_dir).join("config.toml"); if !config_file.exists() { - return Self::read_from_fallback_path(); + return Ok((Self::read_from_fallback_path()?, None)); } - let content: String = fs::read_to_string(config_file).unwrap(); + let content: String = fs::read_to_string(&config_file).unwrap(); match toml::from_str(&content) { - Ok(res) => Ok(res), + Ok(res) => Ok((res, Some(config_file))), Err(e) => Err(Report::new(e).suggestion(ERROR_TEXT)), } } else { - Ok(Self::read_from_fallback_path()?) + Ok((Self::read_from_fallback_path()?, None)) } } diff --git a/src/util/template.rs b/src/util/template.rs index 241d20b..b55ca22 100644 --- a/src/util/template.rs +++ b/src/util/template.rs @@ -15,6 +15,8 @@ use crate::util::color::color_to_string; use crate::util::filters::set_lightness; use crate::util::variables::format_hook_text; +use std::fs::canonicalize; +use std::path::Path; use std::str; use std::process::{Command, Stdio}; @@ -81,6 +83,26 @@ struct ColorVariants { use super::color::rgb_from_argb; +pub trait StripCanonicalization where Self: AsRef { + #[cfg(not(target_os = "windows"))] + fn strip_canonicalization(&self) -> PathBuf { + self.as_ref().to_path_buf() + } + + #[cfg(target_os = "windows")] + fn strip_canonicalization(&self) -> PathBuf { + const VERBATIM_PREFIX: &str = r#"\\?\"#; + let p = self.as_ref().display().to_string(); + if p.starts_with(VERBATIM_PREFIX) { + PathBuf::from(&p[VERBATIM_PREFIX.len()..]) + } else { + self.as_ref().to_path_buf() + } + } +} + +impl StripCanonicalization for PathBuf {} + pub fn check_string_value(value: &Value) -> Option<&String> { match value { Value::String(v) => Some(v), @@ -114,6 +136,7 @@ impl Template { default_scheme: &SchemesEnum, custom_keywords: &Option>, path_prefix: &Option, + config_path: Option ) -> Result<(), Report> { let default_prefix = "@".to_string(); @@ -156,6 +179,13 @@ impl Template { let input_path_absolute = template.input_path.try_resolve()?; let output_path_absolute = template.output_path.try_resolve()?; + let (input_path_absolute, output_path_absolute) = if config_path.is_some() { + let base = std::fs::canonicalize(&config_path.as_ref().unwrap())?; + (template.input_path.try_resolve_in(&base)?.to_path_buf().strip_canonicalization(), template.output_path.try_resolve_in(&base)?.to_path_buf().strip_canonicalization()) + } else { + (template.input_path.try_resolve()?.to_path_buf(), template.output_path.try_resolve()?.to_path_buf()) + }; + if template.hook.is_some() { format_hook(template, &engine, &mut render_data)?; } @@ -221,8 +251,8 @@ fn export_template( name: &String, render_data: &Value, path_prefix: &Option, - output_path_absolute: std::borrow::Cow, - input_path_absolute: std::borrow::Cow, + output_path_absolute: PathBuf, + input_path_absolute: PathBuf, i: usize, templates: &HashMap, ) -> Result<(), Report> { @@ -242,7 +272,7 @@ fn export_template( })?; let out = if path_prefix.is_some() && !cfg!(windows) { let prefix_path = PathBuf::from(path_prefix.as_ref().unwrap()); - rebase(output_path_absolute.as_ref(), &prefix_path, None) + rebase(&output_path_absolute, &prefix_path, None) .expect("failed to rebase output path") } else { output_path_absolute.to_path_buf() @@ -286,19 +316,17 @@ fn format_hook( ) -> Result<(), Report> { let compared_color: Option = if template.colors_to_compare.is_some() && template.compare_to.is_some() { + let s = engine.compile(template.compare_to.as_ref().unwrap())?; + let compare_to = s.render(&engine, &render_data).to_string()?; Some(color_to_string( &template.colors_to_compare.as_ref().unwrap(), - &template.compare_to.as_ref().unwrap(), + &compare_to, )) } else { None }; Ok( if template.colors_to_compare.is_some() && template.compare_to.is_some() { - color::color_to_string( - &template.colors_to_compare.as_ref().unwrap(), - &template.compare_to.as_ref().unwrap(), - ); let t = engine.compile(template.hook.as_ref().unwrap())?; let res = format_hook_text(render_data, compared_color.as_ref(), t); let mut command = shell(&res); diff --git a/src/util/variables.rs b/src/util/variables.rs index fe8d718..840be2c 100644 --- a/src/util/variables.rs +++ b/src/util/variables.rs @@ -92,4 +92,4 @@ pub fn format_hook_text(render_data: &mut Value, compared_color: Option<&String> .to_string().unwrap(); return data -} +} \ No newline at end of file