1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 12:37:49 +00:00

Merge pull request #4778 from sylvestre/use_humantime_to_duration

Use the humantime_to_duration crate
This commit is contained in:
Daniel Hofstetter 2023-04-25 07:05:03 +02:00 committed by GitHub
commit 714206dd25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 44 deletions

32
Cargo.lock generated
View file

@ -34,6 +34,15 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "aho-corasick"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "aliasable" name = "aliasable"
version = "0.1.3" version = "0.1.3"
@ -569,7 +578,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdaa01904c12a8989dbfa110b41ef27efc432ac9934f691b9732f01cb64dc01" checksum = "7fdaa01904c12a8989dbfa110b41ef27efc432ac9934f691b9732f01cb64dc01"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick 0.7.19",
"byteorder", "byteorder",
"cpp_common", "cpp_common",
"lazy_static", "lazy_static",
@ -1145,6 +1154,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "humantime_to_duration"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d564881e1f668089d5653740167844f6ca8af54cd56bd6951f3dca85ba354fc"
dependencies = [
"regex",
"time",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.53" version = "0.1.53"
@ -1880,11 +1899,11 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f"
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.7.3" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick 1.0.1",
"memchr", "memchr",
"regex-syntax", "regex-syntax",
] ]
@ -1897,9 +1916,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.29" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]] [[package]]
name = "rlimit" name = "rlimit"
@ -3213,6 +3232,7 @@ version = "0.0.18"
dependencies = [ dependencies = [
"clap", "clap",
"filetime", "filetime",
"humantime_to_duration",
"time", "time",
"uucore", "uucore",
"windows-sys 0.45.0", "windows-sys 0.45.0",

View file

@ -1,7 +1,7 @@
# coreutils (uutils) # coreutils (uutils)
# * see the repository LICENSE, README, and CONTRIBUTING files for more information # * see the repository LICENSE, README, and CONTRIBUTING files for more information
# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen # spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime
[package] [package]
name = "coreutils" name = "coreutils"
@ -286,6 +286,7 @@ fundu = "0.5.0"
gcd = "2.3" gcd = "2.3"
glob = "0.3.1" glob = "0.3.1"
half = "2.2" half = "2.2"
humantime_to_duration = "0.1.2"
indicatif = "0.17" indicatif = "0.17"
is-terminal = "0.4.6" is-terminal = "0.4.6"
itertools = "0.10.5" itertools = "0.10.5"

View file

@ -69,6 +69,8 @@ skip = [
{ name = "linux-raw-sys", version = "0.1.4" }, { name = "linux-raw-sys", version = "0.1.4" },
# is-terminal # is-terminal
{ name = "windows-sys", version = "0.45.0" }, { name = "windows-sys", version = "0.45.0" },
# cpp_macros
{ name = "aho-corasick", version = "0.7.19" },
] ]
# spell-checker: enable # spell-checker: enable

View file

@ -1,3 +1,4 @@
# spell-checker:ignore humantime
[package] [package]
name = "uu_touch" name = "uu_touch"
version = "0.0.18" version = "0.0.18"
@ -17,6 +18,7 @@ path = "src/touch.rs"
[dependencies] [dependencies]
filetime = { workspace=true } filetime = { workspace=true }
clap = { workspace=true } clap = { workspace=true }
humantime_to_duration = { workspace=true }
time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] } time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] }
uucore = { workspace=true, features=["libc"] } uucore = { workspace=true, features=["libc"] }

View file

@ -6,7 +6,7 @@
// For the full copyright and license information, please view the LICENSE file // For the full copyright and license information, please view the LICENSE file
// that was distributed with this source code. // that was distributed with this source code.
// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond // spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond humantime
use clap::builder::ValueParser; use clap::builder::ValueParser;
use clap::{crate_version, Arg, ArgAction, ArgGroup, Command}; use clap::{crate_version, Arg, ArgAction, ArgGroup, Command};
@ -83,7 +83,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
) { ) {
(Some(reference), Some(date)) => { (Some(reference), Some(date)) => {
let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?; let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?;
if let Some(offset) = parse_relative_time(date) { if let Ok(offset) = humantime_to_duration::from_str(date) {
let mut seconds = offset.whole_seconds(); let mut seconds = offset.whole_seconds();
let mut nanos = offset.subsec_nanoseconds(); let mut nanos = offset.subsec_nanoseconds();
if nanos < 0 { if nanos < 0 {
@ -428,7 +428,7 @@ fn parse_date(s: &str) -> UResult<FileTime> {
} }
} }
if let Some(duration) = parse_relative_time(s) { if let Ok(duration) = humantime_to_duration::from_str(s) {
let now_local = time::OffsetDateTime::now_local().unwrap(); let now_local = time::OffsetDateTime::now_local().unwrap();
let diff = now_local.checked_add(duration).unwrap(); let diff = now_local.checked_add(duration).unwrap();
return Ok(local_dt_to_filetime(diff)); return Ok(local_dt_to_filetime(diff));
@ -437,39 +437,6 @@ fn parse_date(s: &str) -> UResult<FileTime> {
Err(USimpleError::new(1, format!("Unable to parse date: {s}"))) Err(USimpleError::new(1, format!("Unable to parse date: {s}")))
} }
fn parse_relative_time(s: &str) -> Option<Duration> {
// Relative time, like "-1 hour" or "+3 days".
//
// TODO Add support for "year" and "month".
// TODO Add support for times without spaces like "-1hour".
let tokens: Vec<&str> = s.split_whitespace().collect();
match &tokens[..] {
[num_str, "fortnight" | "fortnights"] => num_str
.parse::<i64>()
.ok()
.map(|n| time::Duration::weeks(2 * n)),
["fortnight" | "fortnights"] => Some(time::Duration::weeks(2)),
[num_str, "week" | "weeks"] => num_str.parse::<i64>().ok().map(time::Duration::weeks),
["week" | "weeks"] => Some(time::Duration::weeks(1)),
[num_str, "day" | "days"] => num_str.parse::<i64>().ok().map(time::Duration::days),
["day" | "days"] => Some(time::Duration::days(1)),
[num_str, "hour" | "hours"] => num_str.parse::<i64>().ok().map(time::Duration::hours),
["hour" | "hours"] => Some(time::Duration::hours(1)),
[num_str, "minute" | "minutes" | "min" | "mins"] => {
num_str.parse::<i64>().ok().map(time::Duration::minutes)
}
["minute" | "minutes" | "min" | "mins"] => Some(time::Duration::minutes(1)),
[num_str, "second" | "seconds" | "sec" | "secs"] => {
num_str.parse::<i64>().ok().map(time::Duration::seconds)
}
["second" | "seconds" | "sec" | "secs"] => Some(time::Duration::seconds(1)),
["now" | "today"] => Some(time::Duration::ZERO),
["yesterday"] => Some(time::Duration::days(-1)),
["tomorrow"] => Some(time::Duration::days(1)),
_ => None,
}
}
fn parse_timestamp(s: &str) -> UResult<FileTime> { fn parse_timestamp(s: &str) -> UResult<FileTime> {
// TODO: handle error // TODO: handle error
let now = time::OffsetDateTime::now_utc(); let now = time::OffsetDateTime::now_utc();

View file

@ -608,7 +608,15 @@ fn test_touch_set_date_relative_smoke() {
// > (equivalent to day), the string yesterday is worth one day // > (equivalent to day), the string yesterday is worth one day
// > in the past (equivalent to day ago). // > in the past (equivalent to day ago).
// //
let times = ["yesterday", "tomorrow", "now"]; let times = [
"yesterday",
"tomorrow",
"now",
"2 seconds",
"2 years 1 week",
"2 days ago",
"2 months and 1 second",
];
for time in times { for time in times {
let (at, mut ucmd) = at_and_ucmd!(); let (at, mut ucmd) = at_and_ucmd!();
at.touch("f"); at.touch("f");
@ -617,6 +625,11 @@ fn test_touch_set_date_relative_smoke() {
.no_stderr() .no_stderr()
.no_stdout(); .no_stdout();
} }
let (at, mut ucmd) = at_and_ucmd!();
at.touch("f");
ucmd.args(&["-d", "a", "f"])
.fails()
.stderr_contains("touch: Unable to parse date");
} }
#[test] #[test]