Handle directory-file and file-directory comparisons in the diff

GNU diff treats `diff DIRECTORY FILE` as `diff DIRECTORY/FILE FILE`
This commit is contained in:
Tanmay Patil
2024-04-20 22:12:34 +05:30
parent 46a26e896b
commit 39d2ece187
2 changed files with 46 additions and 0 deletions
+15
View File
@@ -1,4 +1,5 @@
use std::ffi::{OsStr, OsString};
use std::path::PathBuf;
use regex::Regex;
@@ -178,6 +179,20 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
} else {
return Err(format!("Usage: {} <from> <to>", exe.to_string_lossy()));
};
// diff DIRECTORY FILE => diff DIRECTORY/FILE FILE
// diff FILE DIRECTORY => diff FILE DIRECTORY/FILE
let mut from_path: PathBuf = PathBuf::from(&params.from);
let mut to_path: PathBuf = PathBuf::from(&params.to);
if from_path.is_dir() && to_path.is_file() {
from_path.push(to_path.file_name().unwrap());
params.from = from_path.into_os_string();
} else if from_path.is_file() && to_path.is_dir() {
to_path.push(from_path.file_name().unwrap());
params.to = to_path.into_os_string();
}
params.format = format.unwrap_or(Format::default());
Ok(params)
}
+31
View File
@@ -6,6 +6,7 @@
use assert_cmd::cmd::Command;
use diffutilslib::assert_diff_eq;
use predicates::prelude::*;
use std::fs::File;
use std::io::Write;
use tempfile::NamedTempFile;
@@ -234,3 +235,33 @@ fn read_from_stdin() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
#[test]
fn read_from_directory() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("diffutils")?;
let target = "target/integration";
let _ = std::fs::create_dir(target);
let directory = &format!("{target}/d");
let _ = std::fs::create_dir(directory);
let mut a = File::create(&format!("{target}/a")).unwrap();
a.write_all(b"a\n").unwrap();
let mut da = File::create(&format!("{directory}/a")).unwrap();
da.write_all(b"da\n").unwrap();
cmd.arg("-u")
.arg(&format!("{target}/d"))
.arg(&format!("{target}/a"));
cmd.assert().code(predicate::eq(1)).failure();
let output = cmd.output().unwrap().stdout;
assert_diff_eq!(
output,
format!(
"--- {}/d/a\tTIMESTAMP\n+++ {}/a\tTIMESTAMP\n@@ -1 +1 @@\n-da\n+a\n",
target, target
)
);
Ok(())
}