Skip to content

Use write-if-changed pattern in connectrpc-build#22

Merged
iainmcgin merged 1 commit intomainfrom
build/write-if-changed
Apr 1, 2026
Merged

Use write-if-changed pattern in connectrpc-build#22
iainmcgin merged 1 commit intomainfrom
build/write-if-changed

Conversation

@iainmcgin
Copy link
Copy Markdown
Collaborator

Skip writing output files when their content is already identical to what's on disk, preserving mtime so Cargo doesn't spuriously recompile downstream crates.

Why

Cargo's rebuild decision for include!-ed files is mtime-based — rustc's dep-info (.d) file lists every included path, and Cargo compares each one's mtime against the stored fingerprint timestamp. Verified empirically: touch $OUT_DIR/gen.rs (content unchanged) → cargo build -v reports Dirty ...: the file 'gen.rs' has changed (mtime 1774896316s, 1m 14s after last build) and recompiles.

Before this change, touching any single .proto file re-ran the build script (correct, per cargo:rerun-if-changed), which then unconditionally rewrote every output .rs file — bumping all their mtimes and cascading into a full downstream recompile even when N-1 of N generated files were byte-identical.

Change

Two call sites in Config::compile() now go through write_if_changed (read-compare-conditionally-write). The now-unused use std::io::Write is removed. Three tests cover create/skip-identical/overwrite. Uses edition-2024 let-chain syntax for the nested condition.

Prior art

Skip writing output files when content is already identical, preserving
mtime so Cargo doesn't spuriously recompile downstream crates.

Cargo's rebuild decision for include!-ed files is mtime-based (rustc
dep-info lists the file, Cargo compares mtime vs fingerprint). Before
this change, touching any single .proto file re-ran the build script
and unconditionally rewrote every output .rs, bumping all their mtimes
and cascading into a full recompile even when N-1 of N files were
byte-identical.

Mirrors anthropics/buffa#17 and prost-build's write_file_if_changed.
@iainmcgin iainmcgin marked this pull request as ready for review March 30, 2026 18:53
@iainmcgin iainmcgin requested a review from asacamano March 30, 2026 18:53
@iainmcgin iainmcgin enabled auto-merge (squash) March 30, 2026 18:53
@iainmcgin iainmcgin merged commit 2f1f460 into main Apr 1, 2026
10 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Apr 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants