Skip to content

Commit 2d63020

Browse files
committed
du: Add support for reading time-style from environment
Similar as what ls does, but du has an extra compatibility layer described in the GNU manual (and that upstream dev helped me understand: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79113 ).
1 parent b99615c commit 2d63020

File tree

2 files changed

+83
-9
lines changed

2 files changed

+83
-9
lines changed

src/uu/du/src/du.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
666666
};
667667

668668
let time_format = if time.is_some() {
669-
parse_time_style(matches.get_one::<String>("time-style").map(|s| s.as_str()))?.to_string()
669+
parse_time_style(matches.get_one::<String>("time-style"))?
670670
} else {
671671
format::LONG_ISO.to_string()
672672
};
@@ -755,18 +755,40 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
755755
Ok(())
756756
}
757757

758-
fn parse_time_style(s: Option<&str>) -> UResult<&str> {
758+
// Parse --time-style argument, falling back to environment variable if necessary.
759+
fn parse_time_style(s: Option<&String>) -> UResult<String> {
760+
let s = match s {
761+
Some(s) => Some(s.into()),
762+
None => {
763+
match env::var("TIME_STYLE") {
764+
// Per GNU manual, strip `posix-` if present, ignore anything after a newline if
765+
// the string starts with +, and ignore "locale".
766+
Ok(s) => {
767+
let s = s.strip_prefix("posix-").unwrap_or(s.as_str());
768+
let s = match s.chars().next().unwrap() {
769+
'+' => s.split('\n').next().unwrap(),
770+
_ => s,
771+
};
772+
match s {
773+
"locale" => None,
774+
_ => Some(s.to_string()),
775+
}
776+
}
777+
Err(_) => None,
778+
}
779+
}
780+
};
759781
match s {
760-
Some(s) => match s {
761-
"full-iso" => Ok(format::FULL_ISO),
762-
"long-iso" => Ok(format::LONG_ISO),
763-
"iso" => Ok(format::ISO),
782+
Some(s) => match s.as_ref() {
783+
"full-iso" => Ok(format::FULL_ISO.to_string()),
784+
"long-iso" => Ok(format::LONG_ISO.to_string()),
785+
"iso" => Ok(format::ISO.to_string()),
764786
_ => match s.chars().next().unwrap() {
765-
'+' => Ok(&s[1..]),
766-
_ => Err(DuError::InvalidTimeStyleArg(s.into()).into()),
787+
'+' => Ok(s[1..].to_string()),
788+
_ => Err(DuError::InvalidTimeStyleArg(s).into()),
767789
},
768790
},
769-
None => Ok(format::LONG_ISO),
791+
None => Ok(format::LONG_ISO.to_string()),
770792
}
771793
}
772794

tests/by-util/test_du.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ fn test_du_h_precision() {
591591
}
592592
}
593593

594+
#[allow(clippy::too_many_lines)]
594595
#[cfg(feature = "touch")]
595596
#[test]
596597
fn test_du_time() {
@@ -676,6 +677,57 @@ fn test_du_time() {
676677
.succeeds();
677678
result.stdout_only("0\t2016_\n_00\tdate_test\n");
678679

680+
// Time style can also be setup from environment
681+
let result = ts
682+
.ucmd()
683+
.env("TZ", "UTC")
684+
.env("TIME_STYLE", "full-iso")
685+
.arg("--time")
686+
.arg("date_test")
687+
.succeeds();
688+
result.stdout_only("0\t2016-06-16 00:00:00.000000000 +0000\tdate_test\n");
689+
690+
// For compatibility reason, we also allow posix- prefix.
691+
let result = ts
692+
.ucmd()
693+
.env("TZ", "UTC")
694+
.env("TIME_STYLE", "posix-full-iso")
695+
.arg("--time")
696+
.arg("date_test")
697+
.succeeds();
698+
result.stdout_only("0\t2016-06-16 00:00:00.000000000 +0000\tdate_test\n");
699+
700+
// ... and we strip content after a new line
701+
let result = ts
702+
.ucmd()
703+
.env("TZ", "UTC")
704+
.env("TIME_STYLE", "+XXX\nYYY")
705+
.arg("--time")
706+
.arg("date_test")
707+
.succeeds();
708+
result.stdout_only("0\tXXX\tdate_test\n");
709+
710+
// ... and we ignore "locale", fall back to full-iso.
711+
let result = ts
712+
.ucmd()
713+
.env("TZ", "UTC")
714+
.env("TIME_STYLE", "locale")
715+
.arg("--time")
716+
.arg("date_test")
717+
.succeeds();
718+
result.stdout_only("0\t2016-06-16 00:00\tdate_test\n");
719+
720+
// Command line option takes precedence
721+
let result = ts
722+
.ucmd()
723+
.env("TZ", "UTC")
724+
.env("TIME_STYLE", "full-iso")
725+
.arg("--time")
726+
.arg("--time-style=iso")
727+
.arg("date_test")
728+
.succeeds();
729+
result.stdout_only("0\t2016-06-16\tdate_test\n");
730+
679731
for argument in ["--time=atime", "--time=atim", "--time=a"] {
680732
let result = ts
681733
.ucmd()

0 commit comments

Comments
 (0)