mirror of
https://github.com/uutils/coreutils
synced 2024-11-15 01:17:09 +00:00
Merge pull request #1812 from konomith/feature/preserve_timestamps_#1758
install: Implement --preserve-timestamps (-p)
This commit is contained in:
commit
44a7adc9a0
4 changed files with 46 additions and 4 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1687,6 +1687,7 @@ name = "uu_install"
|
|||
version = "0.0.4"
|
||||
dependencies = [
|
||||
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uucore 0.0.7",
|
||||
|
|
|
@ -19,6 +19,7 @@ path = "src/install.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = "2.33"
|
||||
filetime = "0.2"
|
||||
libc = ">= 0.2"
|
||||
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
|
|
@ -13,6 +13,7 @@ mod mode;
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use filetime::{set_file_times, FileTime};
|
||||
use uucore::entries::{grp2gid, usr2uid};
|
||||
use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity};
|
||||
|
||||
|
@ -32,6 +33,7 @@ pub struct Behavior {
|
|||
owner: String,
|
||||
group: String,
|
||||
verbose: bool,
|
||||
preserve_timestamps: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
|
@ -154,11 +156,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
)
|
||||
.arg(
|
||||
// TODO implement flag
|
||||
Arg::with_name(OPT_PRESERVE_TIMESTAMPS)
|
||||
.short("p")
|
||||
.long(OPT_PRESERVE_TIMESTAMPS)
|
||||
.help("(unimplemented) apply access/modification times of SOURCE files to corresponding destination files")
|
||||
.help("apply access/modification times of SOURCE files to corresponding destination files")
|
||||
)
|
||||
.arg(
|
||||
// TODO implement flag
|
||||
|
@ -265,8 +266,6 @@ fn check_unimplemented<'a>(matches: &ArgMatches) -> Result<(), &'a str> {
|
|||
Err("--compare, -C")
|
||||
} else if matches.is_present(OPT_CREATED) {
|
||||
Err("-D")
|
||||
} else if matches.is_present(OPT_PRESERVE_TIMESTAMPS) {
|
||||
Err("--preserve-timestamps, -p")
|
||||
} else if matches.is_present(OPT_STRIP) {
|
||||
Err("--strip, -s")
|
||||
} else if matches.is_present(OPT_STRIP_PROGRAM) {
|
||||
|
@ -338,6 +337,7 @@ fn behavior(matches: &ArgMatches) -> Result<Behavior, i32> {
|
|||
owner: matches.value_of(OPT_OWNER).unwrap_or("").to_string(),
|
||||
group: matches.value_of(OPT_GROUP).unwrap_or("").to_string(),
|
||||
verbose: matches.is_present(OPT_VERBOSE),
|
||||
preserve_timestamps: matches.is_present(OPT_PRESERVE_TIMESTAMPS),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -555,6 +555,21 @@ fn copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> Result<(), ()> {
|
|||
}
|
||||
}
|
||||
|
||||
if b.preserve_timestamps {
|
||||
let meta = match fs::metadata(from) {
|
||||
Ok(meta) => meta,
|
||||
Err(f) => crash!(1, "{}", f.to_string()),
|
||||
};
|
||||
|
||||
let modified_time = FileTime::from_last_modification_time(&meta);
|
||||
let accessed_time = FileTime::from_last_access_time(&meta);
|
||||
|
||||
match set_file_times(to.as_path(), accessed_time, modified_time) {
|
||||
Ok(_) => {}
|
||||
Err(e) => show_info!("{}", e),
|
||||
}
|
||||
}
|
||||
|
||||
if b.verbose {
|
||||
show_info!("'{}' -> '{}'", from.display(), to.display());
|
||||
}
|
||||
|
|
|
@ -309,6 +309,31 @@ fn test_install_target_new_file_failing_nonexistent_parent() {
|
|||
assert!(err.contains("not a directory"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_preserve_timestamps() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file1 = "test_install_target_dir_file_a1";
|
||||
let file2 = "test_install_target_dir_file_a2";
|
||||
at.touch(file1);
|
||||
|
||||
ucmd.arg(file1).arg(file2).arg("-p").succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file1));
|
||||
assert!(at.file_exists(file2));
|
||||
|
||||
let file1_metadata = at.metadata(file1);
|
||||
let file2_metadata = at.metadata(file2);
|
||||
|
||||
assert_eq!(
|
||||
file1_metadata.accessed().ok(),
|
||||
file2_metadata.accessed().ok()
|
||||
);
|
||||
assert_eq!(
|
||||
file1_metadata.modified().ok(),
|
||||
file2_metadata.modified().ok()
|
||||
);
|
||||
}
|
||||
|
||||
// These two tests are failing but should work
|
||||
#[test]
|
||||
fn test_install_copy_file() {
|
||||
|
|
Loading…
Reference in a new issue