Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Invalid epoch values silently fall back to the current date, defeating reproducibility.
Review effort: Balanced
Findings: 1
What changed in this PR
Uses SOURCE_DATE_EPOCH to make generated manpage dates reproducible.
Changes:
- Converts the epoch to a UTC date.
- Adds an integration test for deterministic output.
| File | Description |
|---|---|
src/bin/uudoc.rs |
Selects the manpage date from the environment. |
tests/uudoc/mod.rs |
Verifies epoch-based manpage dates. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| let now = env::var("SOURCE_DATE_EPOCH") | ||
| .ok() | ||
| .and_then(|source_date_epoch| { | ||
| let timestamp = source_date_epoch.parse().ok()?; | ||
| let timestamp = Timestamp::new(timestamp, 0).ok()?; | ||
| let datetime = timestamp.to_zoned(TimeZone::UTC); | ||
| Some(datetime) | ||
| }) | ||
| .unwrap_or_else(Zoned::now); |
There was a problem hiding this comment.
| let now = env::var("SOURCE_DATE_EPOCH") | |
| .ok() | |
| .and_then(|source_date_epoch| { | |
| let timestamp = source_date_epoch.parse().ok()?; | |
| let timestamp = Timestamp::new(timestamp, 0).ok()?; | |
| let datetime = timestamp.to_zoned(TimeZone::UTC); | |
| Some(datetime) | |
| }) | |
| .unwrap_or_else(Zoned::now); | |
| let now = env::var("SOURCE_DATE_EPOCH") | |
| .ok() | |
| .and_then(|s| s.parse().ok()) | |
| .and_then(|s| Timestamp::new(s, 0).ok()) | |
| .map(|t| t.to_zoned(TimeZone::UTC)) | |
| .unwrap_or_else(Zoned::now); |
seems like it would read easier with combinators
|
We can just remove build date instead of freezing it. No? |
|
I think |
b7f6921 to
8f0e529
Compare
| // Convert to string for processing | ||
| let manpage = String::from_utf8(buffer).expect("Invalid UTF-8 in manpage"); | ||
|
|
||
| // Use SOURCE_DATE_EPOCH if set |
There was a problem hiding this comment.
| // Use SOURCE_DATE_EPOCH if set | |
| // Use `SOURCE_DATE_EPOCH` for reproducible builds if set and valid; otherwise use the current time. |
|
GNU testsuite comparison: |
8f0e529 to
96295d7
Compare
|
|
||
| use std::{ | ||
| collections::HashMap, | ||
| env, |
There was a problem hiding this comment.
error[E0425]: cannot find value `uumain` in module `env`
--> /home/runner/work/coreutils/coreutils/target/debug/build/coreutils-09b66ed593f1a000/out/uutils_map.rs:185:23
|
185 | ("env", (env::uumain, env::uu_app)),
| ^^^^^^ not found in `env`
error[E0425]: cannot find value `uu_app` in module `env`
--> /home/runner/work/coreutils/coreutils/target/debug/build/coreutils-09b66ed593f1a000/out/uutils_map.rs:185:36
|
185 | ("env", (env::uumain, env::uu_app)),
| ^^^^^^ not found in `env`
I'm not sure why, but this import needs to be removed and the call should use the fully qualified std::env::var instead.
96295d7 to
90bdb1c
Compare


I noticed the Arch Linux reproducible builds environment flags all man pages as non-reproducible, unless the package is built on the same day:
With this patch the uudoc binary checks if the
SOURCE_DATE_EPOCHenvironment variable is set, then prefers this value if present. This value is guaranteed to be present in the Arch Linux build environment, Debian, and others.I've added a test that runs uudoc with SOURCE_DATE_EPOCH set and checks the timestamp is set accordingly.