chore: bump forge-std 1.16.1 -> 1.16.2, including the prefix rewrite the pin forces - #126
Conversation
forge-std is the only dependency and the version is baked into every import prefix, so the pin, the lockfile, the remappings and all 23 import statements move together. Closes #90 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 13 minutes Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (31)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
…ver it `main` removed the worked example, so this branch's `script/Build.sol` prefix rewrite has no target and the deletion is taken. `main`'s `setUp` additions and its narrowed `LibCodeGen` import in `test/lib/LibFs.buildFileForContract.t.sol` are kept, with only the forge-std prefix rewritten over them. `grep -rn 'forge-std-1\.16\.1\|forge-std 1\.16\.1'` over the merged tree (excluding `dependencies/`, `out/`, `cache/`) returns nothing: all four version surfaces — `foundry.toml`, `soldeer.lock`, `remappings.txt` and 26 import statements across 24 files — read 1.16.2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#119's four `test/src/interface/*.t.sol` suites and `test/src/lib/LibCodeGen.commentPrefix.t.sol` landed after this branch was cut, each importing `forge-std-1.16.1/src/Test.sol`. The merge brought them in untouched, which would have left the pin at 1.16.2 with five files still resolving against a remapping that no longer exists. `grep -rn 'forge-std-1\.16\.1' .` outside `dependencies/`, `out/` and `cache/` now returns zero hits.
Takes #126's forge-std 1.16.2 import prefixes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`test/src/lib/LibFs.requireTag.t.sol`, `LibFs.dirForTag.t.sol`, `LibFs.pathForTaggedContract.t.sol` and `LibFs.buildFileForTaggedContract.t.sol` do not exist on `main`, so #126's rewrite had nothing to rename in them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #90
forge-stdis the repo's only dependency and it was pinned a version behind:1.16.1(published 2026-05-08) against1.16.2(published 2026-07-03, stillthe newest revision on the Soldeer registry as of this PR).
The version is baked into the import prefix, so this is a coordinated rewrite
rather than a lockfile bump. Moved together:
foundry.toml[dependencies] forge-stdsoldeer.lock(version, url, checksum, integrity)remappings.txtsrc/andtest/foundry.toml:22andtest/src/lib/LibFs.isPresent.t.sol:14, both stating that no forge-stdcheatcode creates a symlink
That is the whole diff.
git diff origin/mainon the merge commit is 32 files,+39/-39, and 39 is exactly
31 imports + 1 pin + 1 remapping + 4 lockfile fields + 2 prose lines. Nothing else moves.Note
Re-resolved against post-#56, post-#138
main. #138 deletedscript/Build.sol,src/generated/CodeGennable.soland.github/workflows/build-pointers.yaml; #56 then moved every.t.solintothe
test/src/**mirror tree. This branch's prefix rewrite ofscript/Build.solis dropped — the file is gone — and every hunk it hadagainst
test/lib/*.t.solis re-sited onto itstest/src/lib/destination.Five files that landed on
mainafter this branch was cut carry the oldprefix and are rewritten here too: #119's four
test/src/interface/*.t.solsuites and #107's
test/src/lib/LibCodeGen.commentPrefix.t.sol. That set isderived from a grep over the merged tree, not from a list, and the grep is
re-run to zero afterwards — any other post-base addition would be caught the
same way. The bump itself is untouched. See "What the merges removed from this
PR" below.
Downstream consequence: this is a republish cascade
src/lib/*.solships in the published soldeer package carrying its importprefixes.
src/lib/LibCodeGen.sol,src/lib/LibFs.solandsrc/lib/LibHexString.soleach open withimport {Vm} from "forge-std-1.16.2/src/Vm.sol";, and that literal string iswhat a consumer compiles. So once this lands and
rain-sol-codegenrepublishes,every consumer must have
forge-std 1.16.2installed under exactly thatprefix — a consumer still on
1.16.1getsSource "forge-std-1.16.2/src/Vm.sol" not foundthe moment it takes the new revision.Consumers move their own pin in lockstep with taking this package's bump; they
do not get to take one without the other. This is a fact about the change, not a
reason not to make it.
Where the issue's proposed fix was wrong
The issue proposed
forge soldeer updateas the step that moves the version.Measured here, it does not:
forge-std = "1.16.1"is an exact requirement, soupdatere-resolves to thesame revision and is a no-op. The version has to be raised in
foundry.tomlfirst;
updatethen re-resolves, refreshes the lockfile and downloads the newtree.
Two further things the proposed fix would have left behind, both measured:
soldeerdoes not prune. After bumping the pin and runningupdate,dependencies/forge-std-1.16.1/is still on disk andremappings.txtholdsboth lines:
Deleting the stale directory and re-running
updatedoes not remove itsremapping line either — soldeer merges into
remappings.txtand never dropsentries. Left in place, that line maps a prefix to a path that does not exist
on a clean checkout, and locally (where the old directory survives) it hides
an incomplete prefix rewrite behind a green build. The
remappings.txthereis the single line that
rm -rf dependencies && forge soldeer updateproduces, re-verified on this merge commit against that exact command:
git diff --exit-code -- remappings.txt soldeer.lockreturned 0 afterwards,so both files came back byte-identical to what is committed, with
dependencies/holdingforge-std-1.16.2and nothing else.The issue's
grep -rl 'forge-std-1\.16\.1/'misses the prose, and it onlyreaches
src script test remappings.txt. The two mentions offorge-std 1.16.1are written with a space, not theforge-std-1.16.1/prefix, so the issue's pattern does not reach them;
foundry.toml's own pinis outside the paths it searches. All three are corrected here, and the claim
the prose makes still holds at 1.16.2:
grep -rniE 'function [a-z]*link'over
dependencies/forge-std-1.16.2/srcreturns exactly one line,Vm.sol:1020: function readLink(...), so there is still no cheatcode thatcreates a symlink. Re-run on this merge commit.
What the merges removed from this PR
script/Build.sol— this branch rewrote its one forge-std import. Thefile no longer exists, so the merge takes the deletion. Nothing of the bump is
lost with it: it imported the same
Vm.solevery remaining file does.bump by regenerating
src/generated/CodeGennable.soland showing it came backbyte-identical at 1.16.1, at 1.16.2 and on the merge commit. There is no
committed artifact and no
forge scriptstep in this repo any more, so thatcheck no longer exists to run. It is not replaced — reintroducing a generated
fixture to keep the evidence alive is exactly the scope Strip the
script/Build.solworked example, leave the library lean #138 removed. Theremaining evidence stands on its own: see "Why no new test" below, which shows
the generated text cannot move because
toStringis aforge-binarycheatcode and forge-std 1.16.2 changes no relevant declaration.
build-pointers.yamlas the check Stale soldeer pin: foundry.toml pins forge-std 1.16.1 with 1.16.2 published, and the version is baked into every import prefix #90 names. Stale soldeer pin: foundry.toml pins forge-std 1.16.1 with 1.16.2 published, and the version is baked into every import prefix #90's proposed fix ends"
build-pointers.yamlthen proves the generated artifact is unchanged". Thatworkflow is deleted and this repo no longer calls
rainix-copy-artifacts.yamlat all, so that half of Stale soldeer pin: foundry.toml pins forge-std 1.16.1 with 1.16.2 published, and the version is baked into every import prefix #90 is void rather than unmet. The half that remains —
pin, lockfile, remappings and every import prefix moving together — is fully
covered.
test/lib/*.t.solpath. Move every .t.sol into the test/src/lib mirror tree #56 moved them undertest/src/, soeach of this branch's hunks against them is a rename-vs-modify. The rename
destinations are taken and the prefix rewritten over
main's content, not thebranch's:
main'ssetUpinLibFs.buildFileForContract.t.sol, test: parse the literal the library emitted, not one the test formatted #111's andAn empty meta file is hashed like any other, to keccak256("") #103's rewrites of the constant-string suites, Prove the traversal property over the identifier alphabets #101's
requireContractNamechanges, test: construct the conforming half of the bytesToHex Vm-output property #102's and test: drop the filePrefix assertion its exact pin already subsumes #99's
bytesToHexchanges and Cover the generated directory being created, by making the directory injectable #112'sLibFs.solrestructure are all present unmodified. The
git diff origin/mainarithmeticabove is the proof: if a rename had dropped
main-side content, it would showup there as a deletion, and there are none.
QA
Discriminating tests: no new Solidity test ships, deliberately — see
"Why no new test". The discriminating check for this change is
nix develop -c forge build, which fails whenever any one of the versionsurfaces disagrees with the others and passes only when all agree; it was run
against a broken tree before the fix (evidence below) and against this merge
commit after, and the four mutations below each break it (or
forge soldeer install) individually. The regression oracle is thepre-existing suite: 155 tests in 23 suites, 0 failed on the merge commit,
the same count
main(c816251) runs.Whole-tree check on the merge commit:
grep -rn 'forge-std-1\.16\.1\|forge-std 1\.16\.1\|forge-std~1\.16\.1\|1_16_1'excluding
dependencies/,out/andcache/returns zero hits. Noprefix is left behind.
Mutations applied: four, one per surface the diff moves, run from this
merge commit and restored after. Baseline (unmutated)
forge build --forceexits 0 in the same script, so the harness is proved to run rather than
silently no-op:
src/lib/LibCodeGen.sol:5prefix →forge-std-1.16.1/forge buildError (6275): Source "forge-std-1.16.1/src/Vm.sol" not foundatsrc/lib/LibCodeGen.solremappings.txt→ the 1.16.1 lineforge buildfoundry.tomlpin →1.16.1, then a cleanforge soldeer installas CI doesforge soldeer installFailed to run soldeer: error during remappings operation: dependency not found: forge-std~1.16.1soldeer.lock→ the 1.16.1 revision, then a cleanforge soldeer installforge soldeer installandforge builddependency not found: forge-std~1.16.2; build exit 1, 31 unresolved-source errorsRestored state:
git statusclean,forge build --forceexit 0.Oracle: the existing suite's expected strings, which are hard-coded from
the definition of
vm.toStringrather than read back offLibCodeGen/LibHexString. The artifact-regeneration oracle the originalversion of this PR used is gone with the artifact; see above.
Category check: Stale soldeer pin: foundry.toml pins forge-std 1.16.1 with 1.16.2 published, and the version is baked into every import prefix #90 asks for the pin, the lockfile, the remappings and
every import prefix to move together, and for
build-pointersto prove thegenerated artifact is unchanged. All version surfaces covered plus the two
prose references the issue's grep pattern could not reach; the
build-pointershalf is void, per "What the merges removed" above.README.mdis untouched and needs nothing. The published rain-sol-codegen package ships no dependency metadata, and the README never names the forge-std version its imports require #82 and its PR docs: name the forge-std prerequisite in the README Install section #117 are bothclosed;
grep -in 'forge-std\|1\.16' README.mdon the merge commit returnszero hits, so there is no version named in the README for this bump to
contradict.
Failing before the fix
With the pin, lockfile and remappings at 1.16.2 and the import prefixes not yet
rewritten,
nix develop -c forge build --forceexits 1 with 31unresolved-source errors — one per import statement across all 29 importing
files:
Passing after the fix
On the merge commit,
nix develop -c forge test:nix develop -c forge fmt --checkexits 0.forge coverageoversrc/libis100% lines / statements / branches / funcs (83/83, 95/95, 10/10, 20/20).
cache/fuzz/failureswas deleted before the run so no result is a replay of anearlier counterexample.
Why no new test
The issue flags that
vm.toStringis on the critical path of every constantthis library emits, so a forge-std change could move the generated text. It
cannot here:
toStringis a cheatcode implemented in theforgebinary, whichthe nix flake pins independently of forge-std; forge-std only declares the
interface, and
diff -u forge-std-1.16.{1,2}/src/Vm.solchanges notoStringor
parseBytesdeclaration (124 changed lines: new cheatcode declarations, alastCallGas→lastFrameGasrename that keeps the old name, and doccomments). 1.16.2 is otherwise a documentation and private-member-underscore
rename release across
StdAssertions,StdChains,StdCheats,StdConfig,StdJson,StdMath,StdStorage,StdStyle,StdTomlandStdUtils.A test asserting the pin is the newest published revision would need the network
and would red the day 1.16.3 ships, so it is not written. A test asserting the
version surfaces agree is not written either: the compiler already holds that
invariant, as M1, M2 and M4 above show, and reaching
remappings.txtfromSolidity would mean widening
fs_permissionsfor no coverage the build does notalready give.