From 713220613e16aadf2eeb8d3fecffab646ba5f605 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Fri, 24 Mar 2023 23:57:49 -0700 Subject: [PATCH] Support diffing directories where files are only in one side This was broken in 1e9f43768. Add test. Fixes #500 --- src/files.rs | 13 ++++++++++++- src/main.rs | 5 ++++- tests/cli.rs | 12 ++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/files.rs b/src/files.rs index 1aab69d71..9b92f0396 100644 --- a/src/files.rs +++ b/src/files.rs @@ -3,6 +3,7 @@ use std::io::Read; use std::{ fs, + io::ErrorKind::*, path::{Path, PathBuf}, }; @@ -12,7 +13,11 @@ use walkdir::WalkDir; use crate::exit_codes::EXIT_BAD_ARGUMENTS; use crate::options::FileArgument; -pub fn read_files_or_die(lhs_path: &FileArgument, rhs_path: &FileArgument) -> (Vec, Vec) { +pub fn read_files_or_die( + lhs_path: &FileArgument, + rhs_path: &FileArgument, + missing_as_empty: bool, +) -> (Vec, Vec) { let lhs_res = read_file_arg(lhs_path); let rhs_res = read_file_arg(rhs_path); @@ -20,6 +25,12 @@ pub fn read_files_or_die(lhs_path: &FileArgument, rhs_path: &FileArgument) -> (V // Both files exist, the happy case. (Ok(lhs_src), Ok(rhs_src)) => (lhs_src, rhs_src), + // Proceed if we've been given two paths and only one + // exists. This is important for mercurial diffs when a file + // has been removed. + (Ok(lhs_src), Err(e)) if missing_as_empty && e.kind() == NotFound => (lhs_src, vec![]), + (Err(e), Ok(rhs_src)) if missing_as_empty && e.kind() == NotFound => (vec![], rhs_src), + (lhs_res, rhs_res) => { // Something else went wrong. Print both errors // encountered. diff --git a/src/main.rs b/src/main.rs index 518ea0a19..235fb8609 100644 --- a/src/main.rs +++ b/src/main.rs @@ -237,6 +237,7 @@ fn main() { &rhs_path, &display_options, &diff_options, + false, language_override, ); print_diff_result(&display_options, &diff_result); @@ -280,9 +281,10 @@ fn diff_file( rhs_path: &FileArgument, display_options: &DisplayOptions, diff_options: &DiffOptions, + missing_as_empty: bool, language_override: Option, ) -> DiffResult { - let (lhs_bytes, rhs_bytes) = read_files_or_die(lhs_path, rhs_path); + let (lhs_bytes, rhs_bytes) = read_files_or_die(lhs_path, rhs_path, missing_as_empty); diff_file_content( lhs_display_path, rhs_display_path, @@ -618,6 +620,7 @@ fn diff_directories<'a>( &FileArgument::NamedPath(rhs_path), &display_options, &diff_options, + true, language_override, ) }) diff --git a/tests/cli.rs b/tests/cli.rs index c60ca33b8..33fd89059 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -131,3 +131,15 @@ fn slightly_invalid_utf8() { let predicate_fn = predicate::str::contains("using"); cmd.assert().stdout(predicate_fn); } + +#[test] +fn directory_arguments() { + let mut cmd = Command::cargo_bin("difft").unwrap(); + + cmd.arg("sample_files/dir_before") + .arg("sample_files/dir_after"); + + let predicate_fn = predicate::str::contains("only_in_before.c") + .and(predicate::str::contains("only_in_after_dir.rs")); + cmd.assert().stdout(predicate_fn); +}