Skip to content

Publish CodeGennable so the shipped example compiles from the package - #129

Closed
thedavidmeister wants to merge 2 commits into
mainfrom
2026-08-16-issue-76
Closed

Publish CodeGennable so the shipped example compiles from the package#129
thedavidmeister wants to merge 2 commits into
mainfrom
2026-08-16-issue-76

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Important

OBSOLETE against post-#138 main — this branch is now an empty diff.
Left open for the human to rule on; nothing here is a close decision.

The dangling import this PR fixes no longer exists. #138 deleted
script/Build.sol (the only file that imported
../test/concrete/CodeGennable.sol) and src/generated/CodeGennable.sol
(the orphaned artifact beside it). git show origin/main:script/Build.sol
no such path. Nothing in the published tree points into test/ any more.

Landing the move now would be a regression, not a no-op: it would push a
test-only fixture — an empty contract whose whole purpose is to give the suite
a non-zero codehash — into src/, and therefore into the published soldeer
package, with no consumer for it. .soldeerignore's /test currently keeps it
out.

main was merged in and its layout taken. git diff origin/main on the merge
commit is empty.

Relationship to #76, restated. #76 is still OPEN and this branch no
longer closes it. #76 has two halves:

So #76's remaining live content lives in rainix. Whether #76 closes here is the
human's call, not this PR's.


Original PR description, kept for the record.

Closes #76.

What this is

Issue #76 has two halves. This PR is the repo half — removing the dangling
import so the package is internally consistent. The CI half (a job that compiles
the package as published, on every push) is in rainix, not here:
rainlanguage/rainix#316. Neither is complete on its own, so please
treat the two as one landing.

The decision the issue left open

The issue offered two routes and this takes the first, deliberately.

  • Move CodeGennable into src/concrete/ (taken). Build cost: one file
    move plus three import repoints. Carrying cost: the package ships one extra
    8-line empty contract with no imports — and its output,
    src/generated/CodeGennable.sol, already shipped, orphaned, alongside a
    script/Build.sol that already shipped and could not compile. Removing it
    later is deleting one file.
  • Add /script to .soldeerignore (rejected). Build cost: one line.
    Carrying cost: the library's only worked example — the thing a consumer
    copies — is dropped from the package entirely, and .soldeerignore grows
    another hand-maintained entry. The issue's own thesis is that .soldeerignore
    being a second definition of the library is the hazard; adding to it moves
    away from the fix. Removing it later means re-adding the example and its
    dependency, i.e. doing this PR anyway.

Imports changed

Other agents are in these files, so exactly:

file before after
script/Build.sol:8 "../test/concrete/CodeGennable.sol" "../src/concrete/CodeGennable.sol"
test/lib/LibFs.buildFileForContract.t.sol:8 "test/concrete/CodeGennable.sol" "src/concrete/CodeGennable.sol"
test/lib/LibCodeGen.bytecodeHashConstantString.t.sol:8 "../concrete/CodeGennable.sol" "src/concrete/CodeGennable.sol"

The third was relative and is now root-relative, matching the sibling import on
line 6 of the same file. #56 moves test/lib/ to test/src/lib/; a
root-relative import survives that move, a ../-relative one does not.

test/concrete/CodeGennable.sol moved to src/concrete/CodeGennable.sol with
git mv (content unchanged, =0.8.25 concrete pragma unchanged). Nothing else
in the repo referenced it. .audit/scope.json still lists the old path and is
left alone — it is a frozen record of the audit at commit 7aa85a4, not a
manifest.

QA

  • Discriminating tests: rainix-static soldeer-package-build (ci(sol): build the tree .soldeerignore publishes, not the repo tree rainix#316)
    run against this repo — fails on base (935c725, exit 1,
    Error (6275): Source "test/concrete/CodeGennable.sol" not found at
    script/Build.sol:8), exit 0 on this branch. forge test is green on both
    base and branch, which is precisely the finding — no test in this repo can
    discriminate, because the repo tree is complete and only the published tree is
    broken.
  • Mutations applied: M1 script/Build.sol:8 import → ../test/concrete/
    → killed by soldeer-package-build (exit 1), survived by forge test;
    M2 LibFs.buildFileForContract.t.sol:8test/concrete/ → killed by
    forge test; M3 LibCodeGen.bytecodeHashConstantString.t.sol:8
    ../concrete/ → killed by forge test; M4 delete
    src/concrete/CodeGennable.sol → killed by both.
  • Oracle: the published artifact itself — the zip
    forge soldeer push --dry-run would upload, built in a scratch project the
    way a consumer builds after soldeer install. Expected behaviour comes from
    .soldeerignore plus the package contents, independently of this repo's
    source tree or its suite.
  • Category check: the issue asks for two halves — (1) a CI job that compiles
    the package as published on every push, (2) removing the inconsistency now.
    (2) is this PR; (1) is ci(sol): build the tree .soldeerignore publishes, not the repo tree rainix#316. Both are covered, and
    both must land together.

Everything below was run in this clone at 2026-08-16-issue-76, tools from the
flake (nix develop -c ...).

Failing first. The reproduction is the new rainix check
rainix-static soldeer-package-build, run against this repo at 935c725
(unmodified main). It builds what .soldeerignore would publish, in a scratch
project, and it is red:

Unable to resolve imports:
      "../test/concrete/CodeGennable.sol" in "…-scratch/script/Build.sol"
with remappings:
      forge-std-1.16.1/=…-scratch/dependencies/forge-std-1.16.1/
Compiling 24 files with Solc 0.8.25
Error: Compiler run failed:
Error (6275): Source "test/concrete/CodeGennable.sol" not found: File not found.
ParserError: Source "test/concrete/CodeGennable.sol" not found: File not found.
 --> script/Build.sol:8:1:
  |
8 | import {CodeGennable} from "../test/concrete/CodeGennable.sol";
::error::rain-sol-codegen~0.1.13 does not build as published — …
EXIT=1

Passing after. Same command, same scratch dir, after this commit:

Compiling 25 files with Solc 0.8.25
Solc 0.8.25 finished in 647.37ms
Compiler run successful!
soldeer-package-build: clean — rain-sol-codegen~0.1.13 builds as published (10 Solidity files)
EXIT=0

Full suite. nix develop -c forge test
Ran 16 test suites in 2.54s (27.16s CPU time): 134 tests passed, 0 failed, 0 skipped (134 total tests).
nix develop -c forge fmt --check → exit 0.

Mutation matrix. Each mutant applied alone to the committed tree, both
oracles re-run, mutant reverted. Baseline first, to prove the harness runs and
that a green reading is reachable:

mutant soldeer-package-build forge test
(baseline, no mutant) exit 0 exit 0
M1 script/Build.sol import → ../test/concrete/ exit 1 (killed) exit 0 (blind — this is the finding)
M2 LibFs.buildFileForContract.t.sol import → test/concrete/ exit 1 (killed)
M3 bytecodeHashConstantString.t.sol import → ../concrete/ exit 1 (killed)
M4 delete src/concrete/CodeGennable.sol exit 1 (killed) exit 1 (killed)

M1 is the whole issue in one row: reverting only the published file's import
leaves forge test green and reds only the as-published build. Nothing that
existed before this work could see it.

Not touched

.soldeerignore still excludes /foundry.toml, /remappings.txt and
/soldeer.lock, so the published package carries no build config — a consumer
supplies it. That is normal for a soldeer library and the rainix check
scaffolds it the same way a consumer does.

`script/Build.sol` publishes and `.soldeerignore` excludes `/test`, so the
package's only worked example imported a file no consumer receives. Move
`CodeGennable` under `src/concrete/`, alongside the `src/generated/CodeGennable.sol`
it produces, and point every import at it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Aug 16, 2026
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 93850f8a-c850-43be-a2f3-a548ed5a6a3b

📥 Commits

Reviewing files that changed from the base of the PR and between b422d97 and 00429df.

📒 Files selected for processing (4)
  • script/Build.sol
  • src/concrete/CodeGennable.sol
  • test/lib/LibCodeGen.bytecodeHashConstantString.t.sol
  • test/lib/LibFs.buildFileForContract.t.sol

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch moved `test/concrete/CodeGennable.sol` to `src/concrete/` so the
`script/Build.sol` that shipped in the published package could resolve its
import. #138 deleted `script/Build.sol` and `src/generated/CodeGennable.sol`
outright, so there is no shipped example left to compile and nothing in the
published tree points at `test/`.

Keeping the move would now push a test-only fixture into the published package
for no consumer. `main`'s layout is taken: `CodeGennable` stays in
`test/concrete/`, where `.soldeerignore`'s `/test` keeps it out of the package.
This branch is now a no-op against `main`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Closing: this PR is now an empty diff, and the example it exists to publish no
longer exists.

#138 deleted script/Build.sol under a standing ruling that the worked example
leaves this repo entirely, with rainlanguage/rain.deploy as the org's worked
example. script/Build.sol was the only importer of
test/concrete/CodeGennable.sol, so moving that fixture into src/concrete/ to
make it publishable has no beneficiary — it would push a test fixture into the
published package for the benefit of a script that is gone.

The branch took main's layout and changes 0 files.

#76 — the published package is never compiled as published — stays open and
this PR no longer closes it. One half of #76 (shipping a file whose import is
excluded) was resolved by #138's deletion; the other half, a CI job that builds
the package as published, is rainlanguage/rainix#316 and is not this repo's to
land.

Nothing here is lost. The branch is left in place as the audit trail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published package is never compiled as published, and ships a file whose import it excludes

1 participant