+
Skip to content

Conversation

drinkcat
Copy link
Collaborator

@drinkcat drinkcat commented Jul 30, 2025

This fixes #7665, and generally bring du/ls time-style to feature parity with GNU (at least AFAICT...) -- apart from localization.

I was hoping the share more of the code between du and ls, but that seems difficult as the options and parsing is actually different. But at least we can share constants.

Some pr fixes will follow in another MR (that one only support specific FORMAT).


util/build-gnu.sh: Change string matching for tests/ls/time-style-diag.sh

We now are closer to what GNU prints, and handle the [posix-] cases
that they do.

ls: cleanup imports

They were a bit jumbled with no particular logic, at least that
I could see.

ls: Fix Windows build

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 ).

du/ls: Move common time formats to constants in uucore/time

Along the way:

  • Fix the full-iso format, that was supposed to use %N, not %f
    (%f padded with chrono, but not with jiff, and %N is more correct
    and what GNU says in their manual)
  • The Hashmap thing in parse_time_style was too smart, to a point
    that it became too unflexible (it would have been even worse
    when we added locale support).

I was hoping the share more of the code, but that seems difficult.

du: Add support for +FORMAT time-style

Also add to error text, which... GNU coreutils doesn't do for
some reason.

ls: Print dates in the future as "old" ones

ls has different time format for recent (< 6 months) and older files.
Files in the future (even by just a second), are considered old,
which makes sense as we probably want the date to be printed in
that case.

ls: Add support for newline separated format for recent/older

Documented in GNU manual.

Also improve test_ls to test for both recent and older files.

ls: Allow reading time-style from TIME_STYLE environment variable

According to GNU manual.

ls: Add support for --time-style=posix-*

From GNU manual, if LC_TIME=POSIX, then the "locale" timestamp is
used. Else, posix- is stripped and the format is parsed as usual.

Also, just move the whole text to the locale file, instead
of trying to generate it manually.

drinkcat added 7 commits July 30, 2025 17:27
From GNU manual, if LC_TIME=POSIX, then the "locale" timestamp is
used. Else, `posix-` is stripped and the format is parsed as usual.

Also, just move the whole text to the locale file, instead
of trying to generate it manually.
Documented in GNU manual.

Also improve test_ls to test for both recent and older files.
ls has different time format for recent (< 6 months) and older files.
Files in the future (even by just a second), are considered old,
which makes sense as we probably want the date to be printed in
that case.
Also add to error text, which... GNU coreutils doesn't do for
some reason.
Along the way:
 - Fix the full-iso format, that was supposed to use %N, not %f
   (%f padded with chrono, but not with jiff, and %N is more correct
   and what GNU says in their manual)
 - The Hashmap thing in parse_time_style was too smart, to a point
   that it became too unflexible (it would have been even worse
   when we added locale support).

I was hoping the share more of the code, but that seems difficult.
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 ).
Copy link

GNU testsuite comparison:

GNU test failed: tests/ls/ls-time. tests/ls/ls-time is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/ls/time-style-diag. tests/ls/time-style-diag is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/misc/stdbuf (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)

drinkcat added 2 commits July 30, 2025 17:58
They were a bit jumbled with no particular logic, at least that
I could see.
Copy link

GNU testsuite comparison:

GNU test failed: tests/ls/ls-time. tests/ls/ls-time is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/ls/time-style-diag. tests/ls/time-style-diag is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)

@drinkcat drinkcat marked this pull request as draft July 30, 2025 10:26
@drinkcat
Copy link
Collaborator Author

Sigh, looks like I broke GNU tests? Will look.

…g.sh

We now are closer to what GNU prints, and handle the [posix-] cases
that they do.
@drinkcat
Copy link
Collaborator Author

GNU test failed: tests/ls/ls-time. tests/ls/ls-time is passing on 'main'. Maybe you have to rebase?

This is fine, ls-time used to be SKIP, because of the incorrect full-iso format:

$ cargo run ls --full -l --time=mtime a
-rw-rwxr-- 1 drinkcat drinkcat 0 1998-01-15 23:00:00.0 +0800 a
$ ls --full -l --time=mtime a
-rw-rwxr-- 1 drinkcat drinkcat 0 1998-01-15 23:00:00.000000000 +0800 a

I'd rather have a failing test than an incorrectly skipped test, we can fix it later.

tests/ls/time-style-diag: That was a real failure, because we changed the help text.

@drinkcat drinkcat marked this pull request as ready for review July 30, 2025 11:47
Copy link

GNU testsuite comparison:

GNU test failed: tests/ls/ls-time. tests/ls/ls-time is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)

"iso" => Ok("%Y-%m-%d"),
_ => Err(DuError::InvalidTimeStyleArg(s.into()).into()),
Some(s) => match s.as_ref() {
"full-iso" => Ok(format::FULL_ISO.to_string()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to use an enum here ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confused in Rust.... How? ,-P

This is not allowed (you can set values but they need to be isize type:

enum Format {
    FULL_ISO = "%Y-%m-%d %H:%M:%S.%N %z",
    LONG_ISO = "%Y-%m-%d %H:%M",
    ISO = "%Y-%m-%d",
}

https://stackoverflow.com/questions/36928569/how-can-i-create-enums-with-constant-values-in-rust gave me this idea:

pub struct Format;

impl Format {
    pub const FULL_ISO: &str = "%Y-%m-%d %H:%M:%S.%N %z";
    pub const LONG_ISO: &str = "%Y-%m-%d %H:%M";
    pub const ISO: &str = "%Y-%m-%d";
}

This is not so bad (I somewhat prefer using static to const but that's not allowed here... but maybe I'm wrong, I think static and const should behave the same anyway in this case)

---- wait---

Or you mean something like:

enum Format {
   LongIso,
   FullIso,
   Iso,
   Custom(String)
}

That's not awesome. Would work ok in the du case, but really not in the ls case that has quite a bit more logic (and it's probably better performance-wise to collect the String format first and not do more checks at formatting time).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, enum Format {

but please ignore me if it doesn't make sense!

@sylvestre sylvestre merged commit f877f64 into uutils:main Jul 31, 2025
79 of 80 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

du: should support arbitrary format arg to --time-style

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载