Tighten helper binstub parity and PATH lookup#1128
Conversation
Walkthrough
ChangesTemplate Parity Testing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
Greptile SummaryThis PR tightens the four-way binstub sync contract by adding new test coverage across both the Ruby and JavaScript layers and updating the "keep in sync" comment header in all four copies to list every tracked file.
Confidence Score: 4/5Safe to merge; all changes are test and comment improvements with no production logic modified. The only changed production code is exporting spec/shakapacker/binstub_sync_spec.rb — the failure message for the new dummy-sync example could be more complete. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["lib/install/bin/shakapacker-config"] <-->|byte-identical\nbinstub_sync_spec.rb| B["spec/dummy/bin/shakapacker-config"]
A <-->|byte-identical\ncreateB inStub.test.js| C["createBinStub('shakapacker-config')"]
D["lib/install/bin/diff-bundler-config"] <-->|byte-identical\ncreateB inStub.test.js| E["createBinStub('diff-bundler-config')"]
C & E -->|generated by| F["package/configExporter/cli.ts\nexport function createBinStub"]
G["helper_binstubs_spec.rb"] -->|exercises at runtime| A
G -->|exercises at runtime| D
Reviews (1): Last reviewed commit: "Tighten binstub sync coverage and helper..." | Re-trigger Greptile |
Code ReviewOverall: Clean, well-scoped PR that closes real test-coverage gaps. Low risk — no runtime behavior changes. A few minor wording issues worth fixing before merge. What's good
Issues (inline comments posted)
None of these affect correctness. Issue 2 (error message wording) is the most worth fixing since a contributor would read it under pressure. |
27a0e53 to
e1af730
Compare
Address the low-priority polish item from the PR #1104 review. `shakapacker_node_binary` previously verified Node was installed by running `system("node", "--version")`, which forks a subprocess on every binstub invocation just to confirm presence. Replace with a direct ENV["PATH"] walk, falling back to PATHEXT-style extensions on Windows. Cuts a fork+exec from every `bin/shakapacker-config` and `bin/diff-bundler-config` call. Applied identically across the three checked-in helper binstubs (lib/install/bin/shakapacker-config, lib/install/bin/diff-bundler-config, spec/dummy/bin/shakapacker-config) and the createBinStub template in package/configExporter/cli.ts. binstub_sync_spec.rb + test/configExporter/createBinStub.test.js (from PR #1128) keep the four copies byte-aligned. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary Address the **low-priority optimization** from the [PR #1104 follow-up review](#1123). This is **PR 3 of 3** for #1123 — the smallest of the three, isolated so it can land or be punted independently. ### Change `shakapacker_node_binary` in the helper binstubs previously verified Node was installed by running `system("node", "--version")` with both streams piped to `/dev/null`. That forks a subprocess on every binstub invocation — just to learn whether Node exists. Replaced with a direct walk of `ENV["PATH"]` that also probes `PATHEXT`-style extensions on Windows (so `node.exe`/`node.cmd` are still discoverable). One fork+exec saved per `bin/shakapacker-config` and `bin/diff-bundler-config` call. The return value is unchanged (the literal string `"node"`), so the subsequent `exec node_bin, script_path, *ARGV` still goes through the OS's `PATH` resolution exactly as before. Applied byte-identically across all four copies kept in sync by PR #1128 (`binstub_sync_spec.rb` + `test/configExporter/createBinStub.test.js`): - `lib/install/bin/shakapacker-config` - `lib/install/bin/diff-bundler-config` - `spec/dummy/bin/shakapacker-config` - the `createBinStub` template in `package/configExporter/cli.ts` ### Stacked on PR #1128 This branch is stacked on top of `jg/1123-binstub-sync-coverage` (PR #1128). GitHub will auto-update the base to `main` once #1128 merges. If #1128 is closed instead, this PR can rebase onto `main` with a trivial change (only the comment header and `NODE_ENV` line differ, and only the comment-header lines need replaying). Refs #1123. ## Test plan - [x] `bundle exec rspec spec/shakapacker/binstub_sync_spec.rb` — 2 examples pass (dummy↔install parity preserved) - [x] `bundle exec rspec spec/shakapacker/helper_binstubs_spec.rb` — 8 examples pass, including the "node unavailable" path that uses `PATH=/nonexistent` - [x] `yarn jest test/configExporter/createBinStub.test.js` — 2 examples pass (template still matches install templates byte-for-byte) - [x] `bundle exec rubocop` — no offenses on changed Ruby files - [x] `yarn eslint` — no errors on changed TS file - [x] `ruby -c` on all three modified binstubs — syntax OK 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches the helper binstubs used to launch Node-based tooling; any bug in the new `PATH`/`PATHEXT` scan could prevent commands from running, especially on Windows. > > **Overview** > Replaces `shakapacker_node_binary`’s `system("node", "--version")` check with a no-fork scan of `ENV["PATH"]`, including Windows `PATHEXT` extension probing. > > Applies the same updated Node lookup logic across all four synced helper-binstub copies (`lib/install/bin/*`, `spec/dummy/bin/*`, and the `createBinStub` template in `package/configExporter/cli.ts`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1889de4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47492995cc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Code ReviewOverviewThis PR adds a Jest parity test that generates both helper binstubs via Strengths
Issues / Suggestions1. Export comment hard-codes the test file path (minor) If the test file is ever moved or renamed, the comment in 2.
3. The Not a concern here
VerdictApprove with nits. The test closes a real CI gap with a minimal, well-structured change. The nits above are worth a quick fix but not blocking. |
Code ReviewOverall: This is a well-scoped PR that closes a real gap — the existing Ruby sync spec couldn't reach into the JS template inside
|
Code ReviewOverview: Closes a real coverage gap — the Ruby
|
dc4aec2 to
d7202da
Compare
d7202da to
17b6e7f
Compare
|
@claude review this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 340ffa81e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Code ReviewOverviewThis is a well-scoped, low-risk PR that closes a meaningful gap: the embedded Ruby template inside PATH Fix (
|
Address the medium-priority test-coverage follow-ups from the PR #1104 review. 1. Cover spec/dummy/bin/shakapacker-config in the sync spec. The dummy binstub used by the test app must stay byte-identical to the install template; otherwise a stale wrapper could silently mask install- template changes. 2. Add a JS test that invokes createBinStub for both helper binstub names and asserts the generated content is byte-identical to the checked-in lib/install/bin/* files. Exports createBinStub from package/configExporter/cli.ts so the test can reach it. This closes the gap where the Ruby sync spec couldn't reach into the JS template. 3. Assert the `[Shakapacker] No Gemfile found at …` warning in helper_binstubs_spec.rb so the fallback path can't lose its warning silently. 4. Update the "Keep in sync" comment in all four locations to list all four copies (the previous wording said "all three" and missed the dummy binstub). 5. Rename the "documents every divergent binstub and only divergent binstubs" example to "all documented divergent binstubs still exist in both directories" so the name matches what the test actually verifies — the "only" guarantee comes from the iteration loop, not this example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c37ff59 to
291baa6
Compare
Code ReviewOverviewThis PR tightens helper binstub parity and fixes a real edge case: empty PATH segments (leading/trailing PATH bug fix ✅The core fix in all four binstub copies is correct:
Parity test approach ✅
|
Code Review: Tighten helper binstub parity and PATH lookupOverall: looks solid — correct fix, good test coverage, clean refactoring. One minor nit below. PATH fix (lib/install/bin/*, spec/dummy/bin/shakapacker-config, createBinStub template)The Test coverage
createBinStub export + parity testExporting binstub_sync_spec.rb error messageThe updated failure message naming all four copies is a genuine improvement for contributors — much easier to act on than the previous two-copy guidance. Import refactoring in cli.tsMoving Minor nit
|
Address remaining optional review nits on PR #1128: - spec/shakapacker/helper_binstubs_spec.rb: use ENV.fetch("PATH", "") in the real_node_path helper so it degrades gracefully (matching the production binstubs) instead of raising KeyError if PATH is unset. - spec/shakapacker/binstub_sync_spec.rb: clarify the divergence failure message to explain that all four copies must stay byte-for-byte identical, so a contributor who edits only one copy understands the full set to update. Test-only changes; no user-visible behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review trade-off on PR #1128: exporting createBinStub for the parity test widens the importable surface. It is reachable only via the deep package/configExporter/cli path (not the curated ./configExporter entry), but a JSDoc @internal tag documents that it is test-only and not part of the public API, discouraging downstream production use. Comment-only change; the generated template string is untouched, so the byte-for-byte binstub parity test is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@claude please review this PR. Focus on:
Please post your review as a PR comment, and use inline comments for specific code issues. |
…nalyze-webpack-output * origin/main: (164 commits) Make Rspack the default bundler for new installs (#1150) Add "Why Shakapacker with Rspack" comparison guide (#1155) Support sass-loader v17 (#1141) [codex] Fix Claude workflow permissions (#1153) Fix README CI badges and add prominent docs link (#1152) Trim README into a docs-site index; relocate content to docs/ and fix deep links (#1148) Tighten helper binstub parity and PATH lookup (#1128) Optimize CI: minimal version matrix on PRs, full matrix on main (#1151) Fix instance-scoped compiler strategies (#1147) Fix Rspack devServer in static watch mode (#1142) Add homepage links for supplemental npm packages (#1145) Release 10.1.0 Update CHANGELOG.md for v10.1.0 (#1139) Expand prerelease-to-stable changelog coalesce guidance in /update-changelog (#1138) Release 10.1.0-rc.2 [codex] Update changelog for v10.1.0-rc.2 (#1136) Teach /update-changelog to drop RC-only regression fixes (#1125) Restructure supplemental package dependencies (#1131) (#1133) [codex] Add Shakapacker brand assets (#1135) [codex] Fix shakapacker config helper binstubs (#1132) ...
* origin/main: (26 commits) Adopt agent-workflow binstubs (.agents/bin/ + AGENTS.md pointer) (#1176) Fix Ruby 3.1 CI: exclude broken i18n 1.15.0/1.15.1 (Fiber[]) (#1171) Add AI analysis prompt generator to config exporter (#695) Make Rspack the default bundler for new installs (#1150) Add "Why Shakapacker with Rspack" comparison guide (#1155) Support sass-loader v17 (#1141) [codex] Fix Claude workflow permissions (#1153) Fix README CI badges and add prominent docs link (#1152) Trim README into a docs-site index; relocate content to docs/ and fix deep links (#1148) Tighten helper binstub parity and PATH lookup (#1128) Optimize CI: minimal version matrix on PRs, full matrix on main (#1151) Fix instance-scoped compiler strategies (#1147) Fix Rspack devServer in static watch mode (#1142) Add homepage links for supplemental npm packages (#1145) Release 10.1.0 Update CHANGELOG.md for v10.1.0 (#1139) Expand prerelease-to-stable changelog coalesce guidance in /update-changelog (#1138) Release 10.1.0-rc.2 [codex] Update changelog for v10.1.0-rc.2 (#1136) Teach /update-changelog to drop RC-only regression fixes (#1125) ... # Conflicts: # CHANGELOG.md # lib/install/bin/diff-bundler-config # lib/install/bin/shakapacker-config # lib/tasks/shakapacker/export_bundler_config.rake # package/configExporter/cli.ts # spec/dummy/bin/shakapacker-config
## Summary Stamps the **`v10.2.0`** release section in `CHANGELOG.md` and adds the user-visible entries that were still missing for PRs merged since `v10.1.0`. Header format matches the repo convention (`## [v10.2.0] - July 3, 2026`) and is parseable by `rakelib/release.rake`'s `extract_changelog_section` (`## [v<npm-version>]`), so `bundle exec rake release` / `sync_github_release` will pick up the notes automatically. ### Changelog changes - **Version header**: inserted `## [v10.2.0] - July 3, 2026` immediately after `## [Unreleased]`; all accumulated entries now live under it, and `## [Unreleased]` is empty. - **Compare links**: `[unreleased]` now compares `v10.2.0...main`; added `[v10.2.0]: …/compare/v10.1.0...v10.2.0`. ### New entries added (were missing) | PR | Section | Note | | --- | --- | --- | | [#1187](#1187) | Added | Babel 8 peer dependency support + preset option compatibility | | [#1184](#1184) | Added | Folded into the #695 AI-prompt entry (gates the React on Rails section on app detection) | | [#1142](#1142) | Fixed | Rspack dev-server config no longer loads in static watch mode (fixes #1137) | ### Already documented (carried into v10.2.0) `#1180`, `#695`, `#1141`, `#1150`, `#1179`, `#1192`, `#1127`, `#1178`, `#1161`, `#1147`. ### Reviewed and intentionally excluded (not user-visible) Docs: `#1145`, `#1148`, `#1152`, `#1155`, `#1183`, `#1188`, `#1189`, `#1193`. CI: `#1151`, `#1168`, `#1171`. Tests / fixtures: `#1128`, `#1154`, `#1167`, `#1186`. Workflow / agent tooling: `#1153`, `#1176`, `#1182`. (`#1107` is already documented under `## [v10.1.0]`.) ## Next step After merge, run the repo's release task (no args) — it reads `v10.2.0` from the changelog and creates the GitHub release from this section. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Adds focused parity coverage for the helper binstub contract introduced in #1123.
The PR keeps the checked-in Ruby helper wrappers, the dummy app wrapper, and the
createBinStubTypeScript template aligned so future helper drift fails CI quickly.Changes
createBinStubfrompackage/configExporter/cli.tsfor test use.test/configExporter/createBinStub.test.js, which generatesshakapacker-configanddiff-bundler-configand byte-compares them withlib/install/bin/*.mkdirSyncandchmodSyncin the top-levelfsimport instead of using inlinerequire("fs").spec/shakapacker/binstub_sync_spec.rbfailure guidance so contributors are told to update all synchronized copies.Review follow-up
Addressed the current actionable review threads:
test.each(["shakapacker-config", "diff-bundler-config"]).if (tmp)cleanup guard.diff-bundler-configis covered even though production init only generatesshakapacker-config.mkdirSyncandchmodSyncinto the module-levelfsimport.PATHsegment handling so helper binstubs honor the current directory during Node lookup, and added RSpec coverage for both helper commands.Discussion/advice:
PATHsegment handling turned out to be a real edge case: RubyFile.join("", "node")checks/node, not the current directory, and RubyString#splitdrops trailing empty fields unless called with a negative limit. The helper now preserves trailing entries and maps empty segments toDir.pwdbefore joining, preserving normal PATH semantics even though the binstub laterchdirs to the app root.CI note
This branch is rebased onto current
origin/main.The earlier
Test Both Bundlersfailure was Bundler frozen-mode lockfile drift inspec/dummy/Gemfile.lock: the lockfile still recordedshakapacker (10.1.0.rc.1)while the current gemspec resolves to10.1.0. That lockfile fix is now already included in currentorigin/main, and this branch has been rebased on top of it, so the PR diff no longer carries a lockfile change.The previous
claude-reviewfailure was due to the external Claude weekly limit, not the repository diff.Test plan
bundle exec rspec spec/shakapacker/helper_binstubs_spec.rb:211 --format documentation- 4 empty-PATHexamples pass for leading and trailing entries across both helper commandsbundle exec rspec spec/shakapacker/binstub_sync_spec.rb spec/shakapacker/helper_binstubs_spec.rb- 21 examples, 0 failuresyarn jest test/configExporter/createBinStub.test.js- 2 tests passedyarn eslint package/configExporter/cli.ts test/configExporter/createBinStub.test.jsbundle exec rubocop spec/shakapacker/helper_binstubs_spec.rb spec/shakapacker/binstub_sync_spec.rb- no offensesgit diff --check origin/main...HEADRefs #1123.
Note
Low Risk
Changes are confined to install/helper binstub templates and test tooling; behavior fix is narrow (PATH parsing) with new regression coverage.
Overview
Tightens helper binstub parity and fixes Node lookup when
PATHcontains empty segments (leading/trailing:).PATH lookup:
shakapacker_find_executablenow splitsPATHwith a negative limit so trailing empty entries are kept, and treats an empty segment asDir.pwdinstead of joining to/node. The same Ruby logic is updated inlib/install/bin/*,spec/dummy/bin/shakapacker-config, and thecreateBinStubtemplate inpackage/configExporter/cli.ts.Parity & CI:
createBinStubis exported (test-only) and uses top-levelfsimports;test/configExporter/createBinStub.test.jsbyte-compares generatedshakapacker-config/diff-bundler-configstubs tolib/install/bin/*and checks execute bits.binstub_sync_specfailure text lists all four sync targets.helper_binstubs_specadds RSpec for leading/trailing emptyPATHentries, refactorsreal_node_path, and wraps some cases inBundler.with_unbundled_env.Reviewed by Cursor Bugbot for commit 88a44c9. Bugbot is set up for automated code reviews on this repo. Configure here.