Skip to content

Commit 6c6acf3

Browse files
authored
Merge branch 'main' into misc/close-stdout.sh
2 parents 854294f + 2c75e71 commit 6c6acf3

File tree

5 files changed

+89
-75
lines changed

5 files changed

+89
-75
lines changed

.github/workflows/CICD.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,10 +878,14 @@ jobs:
878878
shell: bash
879879
run: |
880880
## Package artifact(s)
881-
# binary
881+
# binaries
882882
cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
883+
cp 'target/${{ matrix.job.target }}/release/uudoc${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' || :
883884
# `strip` binary (if needed)
884-
if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' ; fi
885+
if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then
886+
"${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}'
887+
"${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/uudoc' || :
888+
fi
885889
# README and LICENSE
886890
# * spell-checker:ignore EADME ICENSE
887891
(shopt -s nullglob; for f in [R]"EADME"{,.*}; do cp $f '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' ; done)

.github/workflows/benchmarks.yml

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,38 @@ concurrency:
1818

1919
jobs:
2020
benchmarks:
21-
name: Run benchmarks (CodSpeed)
21+
name: Run ${{ matrix.type }} benchmarks for ${{ matrix.package }} (CodSpeed)
2222
runs-on: ubuntu-latest
2323
strategy:
2424
matrix:
25-
benchmark-target:
26-
- { package: uu_base64 }
27-
- { package: uu_cksum }
28-
- { package: uu_cp }
29-
- { package: uu_cut }
30-
- { package: uu_dd }
31-
- { package: uu_df }
32-
- { package: uu_du }
33-
- { package: uu_expand }
34-
- { package: uu_fold }
35-
- { package: uu_join }
36-
- { package: uu_ls }
37-
- { package: uu_mv }
38-
- { package: uu_nl }
39-
- { package: uu_numfmt }
40-
- { package: uu_rm }
41-
- { package: uu_seq }
42-
- { package: uu_shuf }
43-
- { package: uu_sort }
44-
- { package: uu_split }
45-
- { package: uu_tsort }
46-
- { package: uu_unexpand }
47-
- { package: uu_uniq }
48-
- { package: uu_wc }
49-
- { package: uu_factor }
50-
- { package: uu_date }
25+
type: [performance, memory]
26+
package: [
27+
uu_base64,
28+
uu_cksum,
29+
uu_cp,
30+
uu_cut,
31+
uu_dd,
32+
uu_df,
33+
uu_du,
34+
uu_expand,
35+
uu_fold,
36+
uu_join,
37+
uu_ls,
38+
uu_mv,
39+
uu_nl,
40+
uu_numfmt,
41+
uu_rm,
42+
uu_seq,
43+
uu_shuf,
44+
uu_sort,
45+
uu_split,
46+
uu_tsort,
47+
uu_unexpand,
48+
uu_uniq,
49+
uu_wc,
50+
uu_factor,
51+
uu_date
52+
]
5153
steps:
5254
- uses: actions/checkout@v6
5355
with:
@@ -64,19 +66,23 @@ jobs:
6466
shell: bash
6567
run: cargo install cargo-codspeed --locked
6668

67-
- name: Build benchmarks for ${{ matrix.benchmark-target.package }}
69+
- name: Build benchmarks for ${{ matrix.package }} (${{ matrix.type }})
6870
shell: bash
6971
run: |
70-
echo "Building benchmarks for ${{ matrix.benchmark-target.package }}"
71-
cargo codspeed build -p ${{ matrix.benchmark-target.package }}
72+
echo "Building ${{ matrix.type }} benchmarks for ${{ matrix.package }}"
73+
if [ "${{ matrix.type }}" = "memory" ]; then
74+
cargo codspeed build -m analysis -p ${{ matrix.package }}
75+
else
76+
cargo codspeed build -p ${{ matrix.package }}
77+
fi
7278
73-
- name: Run benchmarks for ${{ matrix.benchmark-target.package }}
79+
- name: Run ${{ matrix.type }} benchmarks for ${{ matrix.package }}
7480
uses: CodSpeedHQ/action@v4
7581
env:
7682
CODSPEED_LOG: debug
7783
with:
78-
mode: simulation
84+
mode: ${{ matrix.type == 'memory' && 'memory' || 'simulation' }}
7985
run: |
80-
echo "Running benchmarks for ${{ matrix.benchmark-target.package }}"
81-
cargo codspeed run -p ${{ matrix.benchmark-target.package }} > /dev/null
86+
echo "Running ${{ matrix.type }} benchmarks for ${{ matrix.package }}"
87+
cargo codspeed run -p ${{ matrix.package }} > /dev/null
8288
token: ${{ secrets.CODSPEED_TOKEN }}

Cargo.lock

Lines changed: 2 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/date/src/date.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
mod locale;
99

1010
use clap::{Arg, ArgAction, Command};
11-
use jiff::fmt::strtime;
11+
use jiff::fmt::strtime::{self, BrokenDownTime, Config, PosixCustom};
1212
use jiff::tz::{TimeZone, TimeZoneDatabase};
1313
use jiff::{Timestamp, Zoned};
1414
use std::collections::HashMap;
@@ -431,21 +431,23 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
431431
let mut stdout = BufWriter::new(std::io::stdout().lock());
432432

433433
// Format all the dates
434+
let config = Config::new().custom(PosixCustom::new()).lenient(true);
434435
for date in dates {
435436
match date {
436-
// TODO: Switch to lenient formatting.
437-
Ok(date) => match strtime::format(format_string, &date) {
438-
Ok(s) => writeln!(stdout, "{s}").map_err(|e| {
439-
USimpleError::new(1, translate!("date-error-write", "error" => e))
440-
})?,
441-
Err(e) => {
442-
let _ = stdout.flush();
443-
return Err(USimpleError::new(
444-
1,
445-
translate!("date-error-invalid-format", "format" => format_string, "error" => e),
446-
));
437+
Ok(date) => {
438+
match BrokenDownTime::from(&date).to_string_with_config(&config, format_string) {
439+
Ok(s) => writeln!(stdout, "{s}").map_err(|e| {
440+
USimpleError::new(1, translate!("date-error-write", "error" => e))
441+
})?,
442+
Err(e) => {
443+
let _ = stdout.flush();
444+
return Err(USimpleError::new(
445+
1,
446+
translate!("date-error-invalid-format", "format" => format_string, "error" => e),
447+
));
448+
}
447449
}
448-
},
450+
}
449451
Err((input, _err)) => {
450452
let _ = stdout.flush();
451453
show!(USimpleError::new(

tests/by-util/test_date.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,8 @@ fn test_date_set_valid_4() {
480480

481481
#[test]
482482
fn test_invalid_format_string() {
483-
let result = new_ucmd!().arg("+%!").fails();
484-
result.no_stdout();
485-
assert!(result.stderr_str().starts_with("date: invalid format "));
483+
// With lenient mode, invalid format sequences are output literally (like GNU date)
484+
new_ucmd!().arg("+%!").succeeds().stdout_is("%!\n");
486485
}
487486

488487
#[test]
@@ -1446,3 +1445,27 @@ fn test_date_locale_fr_french() {
14461445
"Output should include timezone information, got: {stdout}"
14471446
);
14481447
}
1448+
1449+
#[test]
1450+
fn test_date_posix_format_specifiers() {
1451+
let cases = [
1452+
// %r: 12-hour time with zero-padded hour (08:17:48 AM, not 8:17:48 AM)
1453+
("%r", "08:17:48 AM"),
1454+
// %x: locale date in MM/DD/YY format
1455+
("%x", "01/19/97"),
1456+
// %X: locale time in HH:MM:SS format
1457+
("%X", "08:17:48"),
1458+
// %:8z: invalid format (width between : and z) should output literally (lenient mode)
1459+
("%:8z", "%:8z"),
1460+
];
1461+
1462+
for (format, expected) in cases {
1463+
new_ucmd!()
1464+
.env("TZ", "UTC")
1465+
.arg("-d")
1466+
.arg("1997-01-19 08:17:48")
1467+
.arg(format!("+{format}"))
1468+
.succeeds()
1469+
.stdout_is(format!("{expected}\n"));
1470+
}
1471+
}

0 commit comments

Comments
 (0)