Skip to content

Commit

Permalink
Implement -s/--report-identical-files option (fixes #23)
Browse files Browse the repository at this point in the history
  • Loading branch information
oSoMoN authored and sylvestre committed Mar 1, 2024
1 parent a89f30a commit c68d386
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 0 deletions.
41 changes: 41 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 @@ -16,6 +16,7 @@ path = "src/main.rs"

[dependencies]
diff = "0.1.10"
same-file = "1.0.6"

[dev-dependencies]
pretty_assertions = "1"
Expand Down
16 changes: 16 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,25 @@ fn main() -> ExitCode {
to,
context_count,
format,
report_identical_files,
} = parse_params(opts).unwrap_or_else(|error| {
eprintln!("{error}");
exit(2);
});
// if from and to are the same file, no need to perform any comparison
let maybe_report_identical_files = || {
if report_identical_files {
println!(
"Files {} and {} are identical",
from.to_string_lossy(),
to.to_string_lossy(),
)
}
};
if same_file::is_same_file(&from, &to).unwrap_or(false) {
maybe_report_identical_files();
return ExitCode::SUCCESS;
}
// read files
let from_content = match fs::read(&from) {
Ok(from_content) => from_content,
Expand Down Expand Up @@ -71,6 +86,7 @@ fn main() -> ExitCode {
};
io::stdout().write_all(&result).unwrap();
if result.is_empty() {
maybe_report_identical_files();
ExitCode::SUCCESS
} else {
ExitCode::from(1)
Expand Down
56 changes: 56 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Params {
pub to: OsString,
pub format: Format,
pub context_count: usize,
pub report_identical_files: bool,
}

pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params, String> {
Expand All @@ -38,6 +39,7 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
let mut to = None;
let mut format = None;
let mut context_count = 3;
let mut report_identical_files = false;
while let Some(param) = opts.next() {
if param == "--" {
break;
Expand All @@ -52,6 +54,10 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
}
continue;
}
if param == "-s" || param == "--report-identical-files" {
report_identical_files = true;
continue;
}
let p = osstr_bytes(&param);
if p.first() == Some(&b'-') && p.get(1) != Some(&b'-') {
let mut bit = p[1..].iter().copied().peekable();
Expand Down Expand Up @@ -133,6 +139,7 @@ pub fn parse_params<I: IntoIterator<Item = OsString>>(opts: I) -> Result<Params,
to,
format,
context_count,
report_identical_files,
})
}

Expand All @@ -150,6 +157,7 @@ mod tests {
to: os("bar"),
format: Format::Normal,
context_count: 3,
report_identical_files: false,
}),
parse_params([os("diff"), os("foo"), os("bar")].iter().cloned())
);
Expand All @@ -162,6 +170,7 @@ mod tests {
to: os("bar"),
format: Format::Ed,
context_count: 3,
report_identical_files: false,
}),
parse_params([os("diff"), os("-e"), os("foo"), os("bar")].iter().cloned())
);
Expand All @@ -174,6 +183,7 @@ mod tests {
to: os("bar"),
format: Format::Unified,
context_count: 54,
report_identical_files: false,
}),
parse_params(
[os("diff"), os("-u54"), os("foo"), os("bar")]
Expand All @@ -187,6 +197,7 @@ mod tests {
to: os("bar"),
format: Format::Unified,
context_count: 54,
report_identical_files: false,
}),
parse_params(
[os("diff"), os("-U54"), os("foo"), os("bar")]
Expand All @@ -200,6 +211,7 @@ mod tests {
to: os("bar"),
format: Format::Unified,
context_count: 54,
report_identical_files: false,
}),
parse_params(
[os("diff"), os("-U"), os("54"), os("foo"), os("bar")]
Expand All @@ -213,6 +225,7 @@ mod tests {
to: os("bar"),
format: Format::Context,
context_count: 54,
report_identical_files: false,
}),
parse_params(
[os("diff"), os("-c54"), os("foo"), os("bar")]
Expand All @@ -222,13 +235,56 @@ mod tests {
);
}
#[test]
fn report_identical_files() {
assert_eq!(
Ok(Params {
from: os("foo"),
to: os("bar"),
format: Format::Normal,
context_count: 3,
report_identical_files: false,
}),
parse_params([os("diff"), os("foo"), os("bar")].iter().cloned())
);
assert_eq!(
Ok(Params {
from: os("foo"),
to: os("bar"),
format: Format::Normal,
context_count: 3,
report_identical_files: true,
}),
parse_params([os("diff"), os("-s"), os("foo"), os("bar")].iter().cloned())
);
assert_eq!(
Ok(Params {
from: os("foo"),
to: os("bar"),
format: Format::Normal,
context_count: 3,
report_identical_files: true,
}),
parse_params(
[
os("diff"),
os("--report-identical-files"),
os("foo"),
os("bar"),
]
.iter()
.cloned()
)
);
}
#[test]
fn double_dash() {
assert_eq!(
Ok(Params {
from: os("-g"),
to: os("-h"),
format: Format::Normal,
context_count: 3,
report_identical_files: false,
}),
parse_params([os("diff"), os("--"), os("-g"), os("-h")].iter().cloned())
);
Expand Down
41 changes: 41 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,47 @@ fn no_differences() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

#[test]
fn no_differences_report_identical_files() -> Result<(), Box<dyn std::error::Error>> {
// same file
let mut file1 = NamedTempFile::new()?;
file1.write_all("foo\n".as_bytes())?;
for option in ["", "-u", "-c", "-e"] {
let mut cmd = Command::cargo_bin("diffutils")?;
if !option.is_empty() {
cmd.arg(option);
}
cmd.arg("-s").arg(file1.path()).arg(file1.path());
cmd.assert()
.code(predicate::eq(0))
.success()
.stdout(predicate::eq(format!(
"Files {} and {} are identical\n",
file1.path().to_string_lossy(),
file1.path().to_string_lossy(),
)));
}
// two files with the same content
let mut file2 = NamedTempFile::new()?;
file2.write_all("foo\n".as_bytes())?;
for option in ["", "-u", "-c", "-e"] {
let mut cmd = Command::cargo_bin("diffutils")?;
if !option.is_empty() {
cmd.arg(option);
}
cmd.arg("-s").arg(file1.path()).arg(file2.path());
cmd.assert()
.code(predicate::eq(0))
.success()
.stdout(predicate::eq(format!(
"Files {} and {} are identical\n",
file1.path().to_string_lossy(),
file2.path().to_string_lossy(),
)));
}
Ok(())
}

#[test]
fn differences() -> Result<(), Box<dyn std::error::Error>> {
let mut file1 = NamedTempFile::new()?;
Expand Down

0 comments on commit c68d386

Please sign in to comment.