diff --git a/src/actions.rs b/src/actions.rs index a61e01b..c8e7f6b 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -1,11 +1,12 @@ use std::path::Path; use anyhow::{Context, Result}; + use crossterm::style::Stylize; use handlebars::Handlebars; use crate::config::{SymbolicTarget, TemplateTarget, Variables}; -use crate::difference; +use crate::difference::{self, diff_nonempty, generate_template_diff, print_diff}; use crate::filesystem::{Filesystem, SymlinkComparison, TemplateComparison}; #[cfg_attr(test, mockall::automock)] @@ -533,7 +534,29 @@ pub fn update_template( .context("perform template cache")?; Ok(true) } - TemplateComparison::Changed | TemplateComparison::TargetNotRegularFile => { + TemplateComparison::Changed => { + // At this point, we're not sure if there's a difference between the rendered source + // and target, only that the target has been modified in some way. + let diff = generate_template_diff(source, target, handlebars, variables, false) + .context("diff source and target")?; + if diff_nonempty(&diff) { + error!( + "Updating template {:?} -> {:?} but {}. Skipping", + source, target.target, comparison + ); + if log_enabled!(log::Level::Info) { + info!("Refusing because of the following changes in target location: "); + print_diff(diff, diff_context_lines); + } + Ok(false) + } else { + perform_template_deploy(source, cache, target, fs, handlebars, variables) + .context("perform template cache")?; + Ok(true) + } + } + + TemplateComparison::TargetNotRegularFile => { error!( "Updating template {:?} -> {:?} but {}. Skipping.", source, target.target, comparison diff --git a/src/difference.rs b/src/difference.rs index 9cd9256..3d217f8 100644 --- a/src/difference.rs +++ b/src/difference.rs @@ -19,7 +19,7 @@ pub fn print_template_diff( diff_context_lines: usize, ) { if log_enabled!(log::Level::Info) { - match generate_diff(source, target, handlebars, variables) { + match generate_template_diff(source, target, handlebars, variables, true) { Ok(diff) => { if diff_nonempty(&diff) { info!( @@ -41,11 +41,12 @@ pub fn print_template_diff( } } -pub fn generate_diff( +pub fn generate_template_diff( source: &Path, target: &TemplateTarget, handlebars: &Handlebars<'_>, variables: &Variables, + source_to_target: bool, ) -> Result { let file_contents = fs::read_to_string(source).context("read template source file")?; let file_contents = target.apply_actions(file_contents); @@ -56,7 +57,11 @@ pub fn generate_diff( let target_contents = fs::read_to_string(&target.target).context("read template target file")?; - let diff_result = diff::lines(&target_contents, &rendered); + let diff_result = if source_to_target { + diff::lines(&target_contents, &rendered) + } else { + diff::lines(&rendered, &target_contents) + }; Ok(diff_result.into_iter().map(to_owned_diff_result).collect()) } @@ -186,7 +191,7 @@ fn print_hunk(mut left_line: usize, mut right_line: usize, hunk: Diff, max_digit } } -fn print_diff(diff: Diff, extra_lines: usize) { +pub fn print_diff(diff: Diff, extra_lines: usize) { let mut diff = hunkify_diff(diff, extra_lines); let last_hunk = diff.pop().expect("at least one hunk");