diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index bbf90a711..f39d257de 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -666,7 +666,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; let time_format = if time.is_some() { - parse_time_style(matches.get_one::("time-style").map(|s| s.as_str()))?.to_string() + parse_time_style(matches.get_one::("time-style"))? } else { format::LONG_ISO.to_string() }; @@ -755,18 +755,40 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(()) } -fn parse_time_style(s: Option<&str>) -> UResult<&str> { +// Parse --time-style argument, falling back to environment variable if necessary. +fn parse_time_style(s: Option<&String>) -> UResult { + let s = match s { + Some(s) => Some(s.into()), + None => { + match env::var("TIME_STYLE") { + // Per GNU manual, strip `posix-` if present, ignore anything after a newline if + // the string starts with +, and ignore "locale". + Ok(s) => { + let s = s.strip_prefix("posix-").unwrap_or(s.as_str()); + let s = match s.chars().next().unwrap() { + '+' => s.split('\n').next().unwrap(), + _ => s, + }; + match s { + "locale" => None, + _ => Some(s.to_string()), + } + } + Err(_) => None, + } + } + }; match s { - Some(s) => match s { - "full-iso" => Ok(format::FULL_ISO), - "long-iso" => Ok(format::LONG_ISO), - "iso" => Ok(format::ISO), + Some(s) => match s.as_ref() { + "full-iso" => Ok(format::FULL_ISO.to_string()), + "long-iso" => Ok(format::LONG_ISO.to_string()), + "iso" => Ok(format::ISO.to_string()), _ => match s.chars().next().unwrap() { - '+' => Ok(&s[1..]), - _ => Err(DuError::InvalidTimeStyleArg(s.into()).into()), + '+' => Ok(s[1..].to_string()), + _ => Err(DuError::InvalidTimeStyleArg(s).into()), }, }, - None => Ok(format::LONG_ISO), + None => Ok(format::LONG_ISO.to_string()), } } diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index e7bf6dee5..6c4191a20 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -591,6 +591,7 @@ fn test_du_h_precision() { } } +#[allow(clippy::too_many_lines)] #[cfg(feature = "touch")] #[test] fn test_du_time() { @@ -676,6 +677,57 @@ fn test_du_time() { .succeeds(); result.stdout_only("0\t2016_\n_00\tdate_test\n"); + // Time style can also be setup from environment + let result = ts + .ucmd() + .env("TZ", "UTC") + .env("TIME_STYLE", "full-iso") + .arg("--time") + .arg("date_test") + .succeeds(); + result.stdout_only("0\t2016-06-16 00:00:00.000000000 +0000\tdate_test\n"); + + // For compatibility reason, we also allow posix- prefix. + let result = ts + .ucmd() + .env("TZ", "UTC") + .env("TIME_STYLE", "posix-full-iso") + .arg("--time") + .arg("date_test") + .succeeds(); + result.stdout_only("0\t2016-06-16 00:00:00.000000000 +0000\tdate_test\n"); + + // ... and we strip content after a new line + let result = ts + .ucmd() + .env("TZ", "UTC") + .env("TIME_STYLE", "+XXX\nYYY") + .arg("--time") + .arg("date_test") + .succeeds(); + result.stdout_only("0\tXXX\tdate_test\n"); + + // ... and we ignore "locale", fall back to full-iso. + let result = ts + .ucmd() + .env("TZ", "UTC") + .env("TIME_STYLE", "locale") + .arg("--time") + .arg("date_test") + .succeeds(); + result.stdout_only("0\t2016-06-16 00:00\tdate_test\n"); + + // Command line option takes precedence + let result = ts + .ucmd() + .env("TZ", "UTC") + .env("TIME_STYLE", "full-iso") + .arg("--time") + .arg("--time-style=iso") + .arg("date_test") + .succeeds(); + result.stdout_only("0\t2016-06-16\tdate_test\n"); + for argument in ["--time=atime", "--time=atim", "--time=a"] { let result = ts .ucmd()