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

Make relative-paths work with binary files #1740

Merged
merged 3 commits into from
Jul 8, 2024
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ performance/index.html
src/junk.rs
**/*.rs.bk
/target

# insta: unreviewed inline data, and separate snapshot files
*.pending-snap
**/snapshots/*.snap.new
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ default-features = false
features = []

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

[profile.test]
opt-level = 2
Expand Down
55 changes: 47 additions & 8 deletions src/handlers/diff_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,11 @@ impl<'a> StateMachine<'a> {
return Ok(false);
}

let (path_or_mode, file_event) =
let (mut path_or_mode, file_event) =
parse_diff_header_line(&self.line, self.source == Source::GitDiff);

self.minus_file = utils::path::relativize_path_maybe(&path_or_mode, self.config)
.map(|p| p.to_string_lossy().into_owned())
.unwrap_or(path_or_mode);
utils::path::relativize_path_maybe(&mut path_or_mode, self.config);
self.minus_file = path_or_mode;
self.minus_file_event = file_event;

if self.source == Source::DiffUnified {
Expand Down Expand Up @@ -121,12 +120,11 @@ impl<'a> StateMachine<'a> {
return Ok(false);
}
let mut handled_line = false;
let (path_or_mode, file_event) =
let (mut path_or_mode, file_event) =
parse_diff_header_line(&self.line, self.source == Source::GitDiff);

self.plus_file = utils::path::relativize_path_maybe(&path_or_mode, self.config)
.map(|p| p.to_string_lossy().into_owned())
.unwrap_or(path_or_mode);
utils::path::relativize_path_maybe(&mut path_or_mode, self.config);
self.plus_file = path_or_mode;
self.plus_file_event = file_event;
self.painter
.set_syntax(get_filename_from_diff_header_line_file_path(
Expand Down Expand Up @@ -470,6 +468,8 @@ pub fn get_file_change_description_from_file_paths(
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::integration_test_utils::{make_config_from_args, DeltaTest};
use insta::assert_snapshot;

#[test]
fn test_get_filename_from_marker_line() {
Expand Down Expand Up @@ -639,4 +639,43 @@ mod tests {
Some(".config/Code - Insiders/User/settings.json".to_string())
);
}

pub const BIN_AND_TXT_FILE_ADDED: &str = "\
diff --git a/BIN b/BIN
new file mode 100644
index 0000000..a5d0c46
Binary files /dev/null and b/BIN differ
diff --git a/TXT b/TXT
new file mode 100644
index 0000000..323fae0
--- /dev/null
+++ b/TXT
@@ -0,0 +1 @@
+plain text";

#[test]
fn test_diff_header_relative_paths() {
// rustfmt ignores the assert macro arguments, so do the setup outside
let mut cfg = make_config_from_args(&["--relative-paths", "-s"]);
cfg.cwd_relative_to_repo_root = Some("src/utils/".into());
let result = DeltaTest::with_config(&cfg)
.with_input(BIN_AND_TXT_FILE_ADDED)
.output;
// convert windows '..\' to unix '../' paths
insta::with_settings!({filters => vec![(r"\.\.\\", "../")]}, {
assert_snapshot!(result, @r###"

added: ../../BIN (binary file)
───────────────────────────────────────────

added: ../../TXT
───────────────────────────────────────────

───┐
1: │
───┘
│ │ │ 1 │plain text
"###)
});
}
}
3 changes: 3 additions & 0 deletions src/handlers/diff_header_misc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::delta::{DiffType, Source, State, StateMachine};
use crate::utils::path::relativize_path_maybe;

impl<'a> StateMachine<'a> {
#[inline]
Expand Down Expand Up @@ -29,9 +30,11 @@ impl<'a> StateMachine<'a> {
}

if self.minus_file != "/dev/null" {
relativize_path_maybe(&mut self.minus_file, self.config);
self.minus_file.push_str(" (binary file)");
}
if self.plus_file != "/dev/null" {
relativize_path_maybe(&mut self.plus_file, self.config);
self.plus_file.push_str(" (binary file)");
}
return Ok(true);
Expand Down
58 changes: 38 additions & 20 deletions src/tests/test_example_diffs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod tests {
use crate::tests::ansi_test_utils::ansi_test_utils;
use crate::tests::integration_test_utils;
use crate::tests::integration_test_utils::DeltaTest;
use insta::assert_snapshot;

#[test]
fn test_added_file() {
Expand Down Expand Up @@ -126,7 +127,6 @@ mod tests {
"bash",
]);
let output = integration_test_utils::run_delta(MODIFIED_BASH_AND_CSHARP_FILES, &config);
eprintln!("{}", &output);
ansi_test_utils::assert_line_has_syntax_highlighted_substring(
&output,
19,
Expand Down Expand Up @@ -311,37 +311,55 @@ index 0123456..1234567 100644

#[test]
fn test_binary_files_differ() {
let config =
integration_test_utils::make_config_from_args(&["--file-modified-label", "modified:"]);
let output = integration_test_utils::run_delta(BINARY_FILES_DIFFER, &config);
let output = strip_ansi_codes(&output);
assert!(output.contains("\nmodified: foo (binary file)\n"));
let output = DeltaTest::with_args(&["--file-modified-label", "modified:"])
.with_input(BINARY_FILES_DIFFER)
.skip_header();

assert_snapshot!(output, @r###"

modified: foo (binary file)
───────────────────────────────────────────
"###);
}

#[test]
fn test_binary_file_added() {
let config = integration_test_utils::make_config_from_args(&[]);
let output = integration_test_utils::run_delta(BINARY_FILE_ADDED, &config);
let output = strip_ansi_codes(&output);
assert!(output.contains("\nadded: foo (binary file)\n"));
let output = DeltaTest::with_args(&[])
.with_input(BINARY_FILE_ADDED)
.skip_header();
assert_snapshot!(output, @r###"

added: foo (binary file)
───────────────────────────────────────────
"###);
}

#[test]
fn test_binary_file_removed() {
let config = integration_test_utils::make_config_from_args(&[]);
let output = integration_test_utils::run_delta(BINARY_FILE_REMOVED, &config);
let output = strip_ansi_codes(&output);
assert!(output.contains("\nremoved: foo (binary file)\n"));
let output = DeltaTest::with_args(&[])
.with_input(BINARY_FILE_REMOVED)
.skip_header();
assert_snapshot!(output, @r###"

removed: foo (binary file)
───────────────────────────────────────────
"###);
}

#[test]
fn test_binary_files_differ_after_other() {
let config =
integration_test_utils::make_config_from_args(&["--file-modified-label", "modified:"]);
let output = integration_test_utils::run_delta(BINARY_FILES_DIFFER_AFTER_OTHER, &config);
let output = strip_ansi_codes(&output);
assert!(output.contains("\nrenamed: foo ⟶ bar\n"));
assert!(output.contains("\nmodified: qux (binary file)\n"));
let output = DeltaTest::with_args(&["--file-modified-label", "modified:"])
.with_input(BINARY_FILES_DIFFER_AFTER_OTHER)
.output;
assert_snapshot!(output, @r###"


renamed: foo ⟶ bar
───────────────────────────────────────────

modified: qux (binary file)
───────────────────────────────────────────
"###);
}

#[test]
Expand Down
26 changes: 17 additions & 9 deletions src/utils/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@ pub fn absolute_path(relative_path: &str, config: &Config) -> Option<PathBuf> {
.map(normalize_path)
}

/// Relativize path if delta config demands that and paths are not already relativized by git.
pub fn relativize_path_maybe(path: &str, config: &Config) -> Option<PathBuf> {
if config.relative_paths && !calling_process().paths_in_input_are_relative_to_cwd() {
if let Some(base) = config.cwd_relative_to_repo_root.as_deref() {
pathdiff::diff_paths(path, base)
} else {
None
/// Relativize `path` if delta `config` demands that and paths are not already relativized by git.
pub fn relativize_path_maybe(path: &mut String, config: &Config) {
let mut inner_relativize = || -> Option<()> {
let base = config.cwd_relative_to_repo_root.as_deref()?;
let relative_path = pathdiff::diff_paths(&path, base)?;
if relative_path.is_relative() {
#[cfg(target_os = "windows")]
// '/dev/null' is converted to '\dev\null' and considered relative. Work
// around that by leaving all paths like that untouched:
if relative_path.starts_with(Path::new(r"\")) {
return None;
}
*path = relative_path.to_string_lossy().into_owned();
}
} else {
None
Some(())
};
if config.relative_paths && !calling_process().paths_in_input_are_relative_to_cwd() {
let _ = inner_relativize();
}
}

Expand Down
Loading