Skip to content

Commit

Permalink
Set unified context iff needed
Browse files Browse the repository at this point in the history
  • Loading branch information
dandavison committed Aug 1, 2024
1 parent ac27c12 commit 4ae62a9
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 10 deletions.
197 changes: 197 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ features = []

[dev-dependencies]
insta = { version = "1.*", features = ["colors", "filters"] }
rstest = "0.21.0"

[profile.test]
opt-level = 2
Expand Down
80 changes: 70 additions & 10 deletions src/subcommands/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use std::process;

use bytelines::ByteLinesReader;
use itertools::Itertools;

use crate::config::{self, delta_unreachable};
use crate::delta;
Expand All @@ -23,15 +24,27 @@ pub fn diff(
let via_process_substitution =
|f: &Path| f.starts_with("/proc/self/fd/") || f.starts_with("/dev/fd/");

let diff_cmd = if via_process_substitution(minus_file) || via_process_substitution(plus_file) {
format!("diff -U3 {} --", config.diff_args)
} else {
format!("git diff --no-index --color {} --", config.diff_args)
let diff_args = match shell_words::split(&config.diff_args) {
Ok(words) => words,
Err(err) => {
eprintln!("Failed to parse diff args: {}: {err}", config.diff_args);
return config.error_exit_code;
}
};

let mut diff_args = diff_cmd.split_whitespace();
let diff_bin = diff_args.next().unwrap();
let can_use_git = !via_process_substitution(minus_file) && !via_process_substitution(plus_file);
let mut diff_cmd = if can_use_git {
vec!["git", "diff", "--no-index", "--color"]
} else if diff_args_set_unified_context(&diff_args) {
vec!["diff"]
} else {
vec!["diff", "-U3"]
};
diff_cmd.extend(diff_args.iter().map(String::as_str));
diff_cmd.push("--");

let mut diff_cmd = diff_cmd.iter();
let diff_bin = diff_cmd.next().unwrap();
let diff_path = match grep_cli::resolve_binary(PathBuf::from(diff_bin)) {
Ok(path) => path,
Err(err) => {
Expand All @@ -40,8 +53,18 @@ pub fn diff(
}
};

let diff_cmd_string = format!(
"{:?} {} {:?} {:?}",
&diff_path,
diff_cmd.join(" "),
minus_file,
plus_file
);

eprintln!("{}", diff_cmd_string);

let diff_process = process::Command::new(diff_path)
.args(diff_args)
.args(diff_cmd)
.args([minus_file, plus_file])
.stdout(process::Stdio::piped())
.spawn();
Expand Down Expand Up @@ -80,21 +103,58 @@ pub fn diff(
config.error_exit_code
});
if code >= 2 {
eprintln!("'{diff_bin}' process failed with exit status {code}. Command was {diff_cmd}");
eprintln!(
"'{diff_bin}' process failed with exit status {code}. Command was {diff_cmd_string}"
);
config.error_exit_code
} else {
code
}
}

fn diff_args_set_unified_context<I, S>(args: I) -> bool
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
for arg in args {
let arg = arg.as_ref();
if arg == "-u" {
return true;
} else if (arg.starts_with("-U") || arg.starts_with("-u"))
&& arg.split_at(2).1.parse::<u32>().is_ok()
{
return true;
}
}
false
}

#[cfg(test)]
mod main_tests {
use std::io::{Cursor, Read, Seek};
use std::path::PathBuf;

use super::diff;
use super::{diff, diff_args_set_unified_context};
use crate::tests::integration_test_utils;

use rstest::rstest;

#[rstest]
#[case(&["-u"], true)]
#[case(&["-u7"], true)]
#[case(&["-u77"], true)]
#[case(&["-ux"], false)]
#[case(&["-U"], false)]
#[case(&["-U7"], true)]
#[case(&["-U77"], true)]
fn test_unified_diff_arg_is_detected_in_diff_args(
#[case] diff_args: &[&str],
#[case] expected: bool,
) {
assert_eq!(diff_args_set_unified_context(diff_args), expected)
}

#[test]
#[ignore] // https://github.com/dandavison/delta/pull/546
fn test_diff_same_empty_file() {
Expand All @@ -120,7 +180,7 @@ mod main_tests {
}

fn _do_diff_test(file_a: &str, file_b: &str, expect_diff: bool) {
let config = integration_test_utils::make_config_from_args(&[]);
let config = integration_test_utils::make_config_from_args(&["-@-U99"]);
let mut writer = Cursor::new(vec![]);
let exit_code = diff(
&PathBuf::from(file_a),
Expand Down

0 comments on commit 4ae62a9

Please sign in to comment.