1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

install: implement -C / --compare (#1811)

* install: implement `-C` / `--compare`

GNU coreutils [1] checks the following: whether
- either file is nonexistent,
- there's a sticky bit or set[ug]id bit in play,
- either file isn't a regular file,
- the sizes of both files mismatch,
- the destination file's owner differs from intended, or
- the contents of both files mismatch.

[1] https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/install.c?h=v8.32#n174

* Add test: non-regular files

* Forgot a #[test]

* Give up on non-regular file test

* `cargo fmt` install.rs
This commit is contained in:
Antonio Gurgel 2021-03-27 01:18:47 -07:00 committed by GitHub
parent 3ae714e88c
commit 35675fdfe7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 197 additions and 5 deletions

View file

@ -1,4 +1,5 @@
use crate::common::util::*;
use filetime::FileTime;
use rust_users::*;
use std::os::unix::fs::PermissionsExt;
@ -407,3 +408,87 @@ fn test_install_failing_no_such_file() {
assert!(r.code == Some(1));
assert!(r.stderr.contains("No such file or directory"));
}
#[test]
fn test_install_copy_then_compare_file() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let file1 = "test_install_copy_then_compare_file_a1";
let file2 = "test_install_copy_then_compare_file_a2";
at.touch(file1);
scene
.ucmd()
.arg("-C")
.arg(file1)
.arg(file2)
.succeeds()
.no_stderr();
let mut file2_meta = at.metadata(file2);
let before = FileTime::from_last_modification_time(&file2_meta);
scene
.ucmd()
.arg("-C")
.arg(file1)
.arg(file2)
.succeeds()
.no_stderr();
file2_meta = at.metadata(file2);
let after = FileTime::from_last_modification_time(&file2_meta);
assert!(before == after);
}
#[test]
#[cfg(target_os = "linux")]
fn test_install_copy_then_compare_file_with_extra_mode() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
// XXX: can't tests introspect on their own names?
let file1 = "test_install_copy_then_compare_file_with_extra_mode_a1";
let file2 = "test_install_copy_then_compare_file_with_extra_mode_a2";
at.touch(file1);
scene
.ucmd()
.arg("-C")
.arg(file1)
.arg(file2)
.succeeds()
.no_stderr();
let mut file2_meta = at.metadata(file2);
let before = FileTime::from_last_modification_time(&file2_meta);
scene
.ucmd()
.arg("-C")
.arg(file1)
.arg(file2)
.arg("-m")
.arg("1644")
.succeeds()
.no_stderr();
file2_meta = at.metadata(file2);
let after_install_sticky = FileTime::from_last_modification_time(&file2_meta);
assert!(before != after_install_sticky);
// dest file still 1644, so need_copy ought to return `true`
scene
.ucmd()
.arg("-C")
.arg(file1)
.arg(file2)
.succeeds()
.no_stderr();
file2_meta = at.metadata(file2);
let after_install_sticky_again = FileTime::from_last_modification_time(&file2_meta);
assert!(after_install_sticky != after_install_sticky_again);
}