Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: diff source with destination on conflict #117

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/actions.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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
Expand Down
13 changes: 9 additions & 4 deletions src/difference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand All @@ -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<Diff> {
let file_contents = fs::read_to_string(source).context("read template source file")?;
let file_contents = target.apply_actions(file_contents);
Expand All @@ -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())
}
Expand Down Expand Up @@ -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");
Expand Down