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:
parent
3ae714e88c
commit
35675fdfe7
5 changed files with 197 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue