Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
Propagates input read failures in date (file/stdin) instead of treating them as EOF, while continuing past invalid date lines; adds user-facing error reporting and tests to validate behavior.
Changes:
- Introduce
DateInputErrorto distinguish invalid date lines from I/O read failures. - Make the date reader iterator surface read errors and stop iteration after the first read failure.
- Add unit/integration tests and a new localized error string for read-failure reporting.
| File | Description |
|---|---|
| tests/by-util/test_date.rs | Adds a Linux integration test asserting a read error is reported for a problematic input file. |
| src/uu/date/src/date.rs | Adds DateInputError, propagates read errors distinctly, and adds a unit test for reader failure after valid/invalid lines. |
| src/uu/date/locales/en-US.ftl | Adds localized message template for read errors. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
GNU testsuite comparison: |
| when using an option to specify date(s), any non-option | ||
| argument must be a format string beginning with '+' | ||
|
|
||
| date-error-read = {$path}: read error: {$error} |
There was a problem hiding this comment.
did you check the exact GNU wording/exit code with LANG=C?
There was a problem hiding this comment.
Yes. With LANG=C, GNU coreutils 9.12 exits 1, writes no stdout, and reports gnudate: /proc/self/mem: read error: Input/output error on this glibc host. The uutils result matches after normalizing the executable name. The test keeps the OS error suffix flexible because musl spells it I/O error.
| }); | ||
| } | ||
| Err(DateInputError::Read(error)) => { | ||
| stdout.flush().map_err(DateError::Write)?; |
There was a problem hiding this comment.
just above we do let _ = stdout.flush(), could we be consistent?
There was a problem hiding this comment.
Made this consistent with the invalid-date arm by using let _ = stdout.flush() in f4a7f1d.
| } | ||
| Err(DateInputError::Read(error)) => { | ||
| stdout.flush().map_err(DateError::Write)?; | ||
| let path = match &settings.date_source { |
There was a problem hiding this comment.
could you please carry the path in DateInputError::Read? re-deriving it from date_source with a hardcoded "-" fallback is fragile
There was a problem hiding this comment.
DateInputError::Read now carries the input path, including the explicit stdin name, in f4a7f1d.
| DateSource::File(path) => path.as_os_str().maybe_quote().to_string(), | ||
| _ => "-".to_string(), | ||
| }; | ||
| return Err(uucore::error::USimpleError::new( |
There was a problem hiding this comment.
please add a Read variant to DateError instead of USimpleError here
There was a problem hiding this comment.
Added DateError::Read and removed the USimpleError construction in f4a7f1d.
| Box::new(lines.map_while(Result::ok).map(move |mut bytes| { | ||
| ) -> Box<dyn Iterator<Item = Result<ParsedDateTime, DateInputError>> + '_> { | ||
| let mut lines = BufReader::new(reader).split(b'\n'); | ||
| let mut failed = false; |
There was a problem hiding this comment.
the manual failed flag + from_fn is a bit heavy, can't we just fuse after the error?
There was a problem hiding this comment.
Replaced the manual flag and from_fn with a mapped iterator plus scan that yields the first read error and then stops in f4a7f1d.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
parse_dates_from_reader currently uses matches!(result, ...) in a way that moves result, which makes the iterator scan closure not compile as written.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (2)
| if *failed { | ||
| None | ||
| } else { | ||
| *failed = matches!(result, Err(DateInputError::Read { .. })); | ||
| Some(result) | ||
| } |
There was a problem hiding this comment.
Fixed in cdf4e79 by matching on a shared reference to result, so the value remains available for Some(result). cargo test -p uu_date (37 tests) and clippy both pass.
| return Err(Box::new(DateError::Read { | ||
| path, | ||
| error: strip_errno(&error).clone(), | ||
| })); |
There was a problem hiding this comment.
Fixed in cdf4e79 by moving the owned String returned by strip_errno directly into DateError::Read.
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 1
| when using an option to specify date(s), any non-option | ||
| argument must be a format string beginning with '+' | ||
|
|
||
| date-error-read = {$path}: read error: {$error} |
| new_ucmd!() | ||
| .env("LC_ALL", "C") | ||
| .args(&["-f", "/proc/self/mem"]) | ||
| .fails_with_code(1) | ||
| .no_stdout() | ||
| .stderr_contains("/proc/self/mem: read error:"); |



Propagate file/stdin read failures instead of treating them as EOF. Flush completed output, report the input and read error, and exit unsuccessfully. Invalid date lines still allow processing to continue.
Fixes #12672.
Validation: 164 date tests passed, 7 ignored; 37 date unit tests passed, including a reader failing after valid and invalid lines. Clippy and rustfmt passed.
AI-assisted with Codex.