-
-
Notifications
You must be signed in to change notification settings - Fork 638
Fix doctor command false version mismatch for beta/prerelease versions #2064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes #2063 ## Problem The doctor command incorrectly reported version mismatches for beta/alpha/rc versions even when gem and NPM package versions were identical. For example: - Gem: 16.2.0.beta.10 - NPM: 16.2.0-beta.10 Would trigger a false "version mismatch" warning. ## Root Cause The original code (from PR #1787) stripped all non-numeric/non-dot characters from the NPM version for comparison: ```ruby clean_npm_version = npm_version.gsub(/[^0-9.]/, "") # "16.2.0-beta.10" → "16.2.0.10" gem_version = ReactOnRails::VERSION # "16.2.0.beta.10" ``` This removed both the dash AND "beta", turning "16.2.0-beta.10" into "16.2.0.10", which would never match "16.2.0.beta.10". Note: CodeRabbit caught this bug during the original PR review but the suggestion was not implemented. ## Solution Use the existing VersionSyntaxConverter.npm_to_rubygem utility which properly converts NPM semver format (dash separator) to Ruby gem format (dot separator): - "16.2.0-beta.10" → "16.2.0.beta.10" - "^16.2.0-beta.10" → "16.2.0.beta.10" - Handles all prerelease formats: beta, alpha, rc, pre ## Testing Verified with test app using both gem and NPM at 16.2.0.beta.10: - ✅ Matching versions: No false warning - ✅ Caret/tilde prefixes: Handled correctly - ✅ Real mismatches: Still detected properly - ✅ All edge cases: 16/16 test scenarios pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
WalkthroughThe changes fix a version mismatch detection bug where NPM prerelease versions (e.g., Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 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 |
Addresses missing test coverage for the version sync check that was identified during bug investigation. ## Tests Added (9 scenarios) **Matching versions:** - Beta versions: 16.2.0-beta.10 matches 16.2.0.beta.10 - Beta with caret prefix: ^16.2.0-beta.10 - Alpha versions: 16.2.0-alpha.5 - RC versions: 16.2.0-rc.1 - Stable versions: 16.2.0 **Mismatches:** - Minor version mismatch: beta.9 vs beta.10 → warning - Major version mismatch: v15 vs v16 → error **Edge cases:** - No package.json file - Invalid JSON in package.json ## Coverage Impact Before: 31 specs for SystemChecker (check_package_version_sync had 0 tests) After: 40 specs (added 9 tests for check_package_version_sync) All tests pass, ensuring the bug fix works correctly and preventing future regressions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Code Review: Fix doctor command false version mismatch for beta/prerelease versions✅ Overall Assessment: LGTM with minor suggestionsThis is an excellent bug fix that addresses a real issue with prerelease version matching. The solution is clean, well-documented, and leverages existing tested code. 🎯 Strengths
🔍 Code QualityFile: The changes are minimal and focused: # Before (buggy)
clean_npm_version = npm_version.gsub(/[^0-9.]/, "")
# After (correct)
converter = ReactOnRails::VersionSyntaxConverter.new
normalized_npm_version = converter.npm_to_rubygem(npm_version)Correctness: ✅ The fix properly handles:
📋 Suggestions1. Add Test Coverage (Important)While Recommendation: Add a test case like this: describe "#check_package_version_sync" do
context "when versions match with prerelease format" do
let(:package_json_content) do
{ "dependencies" => { "react-on-rails" => "16.2.0-beta.10" } }.to_json
end
before do
allow(File).to receive(:exist?).with("package.json").and_return(true)
allow(File).to receive(:read).with("package.json").and_return(package_json_content)
stub_const("ReactOnRails::VERSION", "16.2.0.beta.10")
end
it "reports matching versions without warnings" do
checker.send(:check_package_version_sync)
expect(checker.messages.any? { |msg| msg[:type] == :success }).to be true
expect(checker.warnings?).to be false
end
end
context "when versions have prerelease mismatch" do
let(:package_json_content) do
{ "dependencies" => { "react-on-rails" => "16.2.0-beta.9" } }.to_json
end
before do
allow(File).to receive(:exist?).with("package.json").and_return(true)
allow(File).to receive(:read).with("package.json").and_return(package_json_content)
stub_const("ReactOnRails::VERSION", "16.2.0.beta.10")
end
it "reports version mismatch warning" do
checker.send(:check_package_version_sync)
expect(checker.warnings?).to be true
expect(checker.messages.last[:content]).to include("Version mismatch detected")
end
end
endThis would prevent future regressions and document the expected behavior. 2. Potential Edge Case: nil handlingLooking at def npm_to_rubygem(npm_version)
match = npm_version
.tr("-", ".")
.strip
.match(/(\d.*)/)
match.present? ? match[0] : nil
endIf Current code at line 229: npm_major = normalized_npm_version.split(".")[0].to_iRecommendation: Add a safety check: if normalized_npm_version.nil?
add_warning("⚠️ Could not parse NPM package version: #{npm_version}")
return
end
if normalized_npm_version == gem_version
# ... rest of the logicHowever, this is likely a theoretical edge case since 3. Minor: Instance CreationThe converter is instantiated but has no state: converter = ReactOnRails::VersionSyntaxConverter.new
normalized_npm_version = converter.npm_to_rubygem(npm_version)Could be simplified to: normalized_npm_version = ReactOnRails::VersionSyntaxConverter.new.npm_to_rubygem(npm_version)But the current approach is perfectly fine and more readable. This is purely stylistic. 🔒 Security Considerations✅ No security concerns. The code processes version strings from ⚡ Performance Considerations✅ Negligible performance impact. Creating one converter instance and calling a simple string transformation method during a diagnostic rake task is trivial. 🧪 Testing RequirementsAccording to
Recommendation before merge: bundle exec rubocop lib/react_on_rails/system_checker.rbThe git hooks should catch this automatically, but worth verifying. 📝 Documentation✅ The PR description is exemplary - it includes:
The inline code comment is clear and helpful. 🎓 Historical ContextExcellent catch noting that CodeRabbit flagged this during the original PR #1787 review but it wasn't addressed. This reinforces the value of code review feedback! Final Recommendation: APPROVE ✅This PR successfully fixes a real bug with a clean, well-thought-out solution. The only improvement I'd strongly recommend is adding test coverage for Merge checklist:
Great work! 🎉 Reviewed using project guidelines from |
Code Review - PR #2064: Fix doctor command false version mismatch✅ Overall AssessmentThis is an excellent fix that resolves a real bug with a clean, well-tested solution. The PR demonstrates strong understanding of the codebase and follows best practices. 🎯 Strengths1. Problem Identification
2. Solution Quality
3. Test Coverage
4. Documentation
🔍 Potential Issues & Suggestions1. Nil Handling Edge Case
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
spec/lib/react_on_rails/system_checker_spec.rb (1)
324-481: New#check_package_version_synccoverage is thorough and matches the intended behaviorThis block does a good job exercising all the important paths: missing
package.json, matching prerelease variants (beta/alpha/rc) and stable, caret‑prefixed prerelease (success + warning), minor vs major mismatches, and invalid JSON handling. The use ofstub_constper context keepsReactOnRails::VERSIONexplicit and aligned with each scenario.If you want to lock in parity with all prerelease formats mentioned in the PR description, you could optionally add one more example for a
-pre/.prepairing, but the current suite already gives solid confidence in the new normalization logic.lib/react_on_rails/system_checker.rb (1)
216-221: Switch toVersionSyntaxConvertercorrectly fixes prerelease comparisonNormalizing the npm version via
ReactOnRails::VersionSyntaxConverter#npm_to_rubygemand comparingnormalized_npm_versiontoReactOnRails::VERSIONis the right move here and should resolve the beta/alpha/rc false mismatches (e.g.,"16.2.0-beta.10"→"16.2.0.beta.10"). Using the normalized value as the basis fornpm_majoralso keeps the major‑version check consistent.Guard against
nilfromnpm_to_rubygemto avoid relying on generic rescueIn edge cases where the npm spec has no digits at all (e.g.,
"latest"or a pure git URL),npm_to_rubygemcan returnnil, which will causenormalized_npm_version.split('.')to raise and be swallowed by the broadrescue StandardError. It’d be cleaner and cheaper to handle that explicitly before splitting, e.g.:- normalized_npm_version = converter.npm_to_rubygem(npm_version) + normalized_npm_version = converter.npm_to_rubygem(npm_version) + return unless normalized_npm_versionThis keeps behavior graceful without depending on an exception path for control flow.
Also applies to: 223-223, 229-229
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
lib/react_on_rails/system_checker.rb(1 hunks)spec/lib/react_on_rails/system_checker_spec.rb(1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.
Applied to files:
spec/lib/react_on_rails/system_checker_spec.rblib/react_on_rails/system_checker.rb
📚 Learning: 2025-09-29T14:45:42.687Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1833
File: lib/react_on_rails/dev/process_manager.rb:72-83
Timestamp: 2025-09-29T14:45:42.687Z
Learning: In Ruby bundler contexts, when bundler intercepts system commands for executables not in the Gemfile, both version checks (like `system("foreman", "--version")`) and execution commands (like `system("foreman", "start", ...)`) fail equally, both returning false. This means availability checks using version flags accurately reflect whether execution commands will work in the current bundler context.
Applied to files:
spec/lib/react_on_rails/system_checker_spec.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.
Applied to files:
lib/react_on_rails/system_checker.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.
Applied to files:
lib/react_on_rails/system_checker.rb
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
Applied to files:
lib/react_on_rails/system_checker.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.
Applied to files:
lib/react_on_rails/system_checker.rb
🧬 Code graph analysis (2)
spec/lib/react_on_rails/system_checker_spec.rb (2)
lib/generators/react_on_rails/generator_messages.rb (1)
messages(21-23)lib/react_on_rails/system_checker.rb (2)
warnings?(36-38)errors?(32-34)
lib/react_on_rails/system_checker.rb (2)
lib/react_on_rails/version_syntax_converter.rb (1)
npm_to_rubygem(14-20)lib/react_on_rails/version_checker.rb (1)
gem_version(203-205)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: dummy-app-integration-tests (3.4, 22, latest)
- GitHub Check: rspec-package-tests (3.4, latest)
- GitHub Check: build
- GitHub Check: claude-review
Code Review - PR #2064: Fix doctor command false version mismatch for beta/prerelease versions✅ Overall AssessmentLGTM with minor suggestions. This is an excellent bug fix that properly addresses the root cause identified in #2063. The solution is clean, well-tested, and leverages existing infrastructure. 🎯 Strengths
🔍 Code Quality Observationslib/react_on_rails/system_checker.rb:216-219Good:
Minor Concern - Performance:
🧪 Test Coverage AnalysisThe test suite in ✅ Happy paths:
✅ Error cases:
✅ Edge cases:
One potential gap: The tests don't explicitly verify that the it "uses VersionSyntaxConverter for version normalization" do
converter = instance_double(ReactOnRails::VersionSyntaxConverter)
allow(ReactOnRails::VersionSyntaxConverter).to receive(:new).and_return(converter)
allow(converter).to receive(:npm_to_rubygem).with("16.2.0-beta.10").and_return("16.2.0.beta.10")
checker.send(:check_package_version_sync)
expect(converter).to have_received(:npm_to_rubygem)
endHowever, this is optional since the integration tests already verify the correct behavior. 🔐 Security Considerations✅ No security concerns identified:
⚡ Performance Considerations✅ Performance impact is negligible:
📋 Suggestions1. Optional: Memoize converter (low priority)If you want to micro-optimize: def version_converter
@version_converter ||= ReactOnRails::VersionSyntaxConverter.new
end
# Then use:
normalized_npm_version = version_converter.npm_to_rubygem(npm_version)But honestly, this is unnecessary given the usage pattern. 2. Consider adding a test comment referencing the bugIn # Regression test for #2063 - Doctor command false version mismatch for beta/prerelease versions
describe "#check_package_version_sync" doThis helps future maintainers understand why these tests exist. 📚 Documentation & Changelog✅ PR description is excellent:
Suggested entry: #### Fixed
- [PR 2064](https://github.com/shakacode/react_on_rails/pull/2064) by [username](https://github.com/username): Fixed `react_on_rails:doctor` command showing false version mismatch warnings for beta/alpha/rc/pre versions. The doctor now correctly compares NPM prerelease versions (e.g., `16.2.0-beta.10`) with gem versions (e.g., `16.2.0.beta.10`).✅ Pre-Merge ChecklistBefore merging, ensure:
🎓 Learning MomentThis PR is a textbook example of how code review feedback (CodeRabbit's comment on #1787) can prevent bugs. The original implementation used an overly aggressive regex that stripped prerelease identifiers along with version prefixes. Key takeaway: When dealing with versioning, always test with prerelease versions (alpha, beta, rc), not just stable versions. Final VerdictApproved with minor changelog addition needed. This is high-quality work that:
Great job! 🚀 Review conducted using project guidelines from CLAUDE.md |
|
thanks @ihabadham |
…se-otp-timing * origin/master: (27 commits) Fix doctor command false version mismatch for beta/prerelease versions (#2064) Fix beta/RC version handling in generator (#2066) Document Rails Engine development nuances and add tests for automatic rake task loading (#2067) Add /run-skipped-tests as alias for /run-skipped-ci (#XXXX) (#2068) Fix: Add Rails 5.2-6.0 compatibility for compact_blank (#2058) Break CI circular dependency with non-docs change (#2065) Fix CI safety check to evaluate latest workflow attempt (#2062) Fix yalc publish (#2054) Add Shakapacker 9.0+ private_output_path integration for server bundles (#2028) Consolidate all beta versions into v16.2.0.beta.10 (#2057) Improve reliability of CI debugging scripts (#2056) Clarify monorepo changelog structure in documentation (#2055) Bump version to 16.2.0.beta.10 Bump version to 16.2.0.beta.9 Fix duplicate rake task execution by removing explicit task loading (#2052) Simplify precompile hook and restore Pro dummy app to async loading (#2053) Add Shakapacker precompile hook with ReScript support to Pro dummy app (#1977) Guard master docs-only pushes and ensure full CI runs (#2042) Refactor: Extract JS dependency management into shared module (#2051) Add workflow to detect invalid CI command attempts (#2037) ... # Conflicts: # rakelib/release.rake
Summary
Fixes #2063 - The doctor command was incorrectly reporting version mismatches for beta/alpha/rc versions even when gem and NPM package versions were identical.
Problem
When running
rake react_on_rails:doctorwith matching prerelease versions:16.2.0.beta.1016.2.0-beta.10The doctor would show a false warning:
Root Cause
The original code from PR #1787 used
gsub(/[^0-9.]/, "")to strip all non-numeric/non-dot characters:"16.2.0-beta.10""16.2.0.10"(both dash AND "beta" removed)"16.2.0.beta.10"(gem version)Note: CodeRabbit caught this bug during the original PR review but the suggestion was not implemented.
Solution
Use the existing
VersionSyntaxConverter.npm_to_rubygemutility which properly handles NPM-to-Ruby version format conversion:^,~,=)-beta) to Ruby gem format (.beta)Changes
File:
lib/react_on_rails/system_checker.rbBefore:
After:
Testing
Verified with test app using both gem and NPM at
16.2.0.beta.10:✅ Matching versions: No false warning
✅ Caret/tilde prefixes: Handled correctly with appropriate warning
✅ Real mismatches: Still detected properly
✅ All prerelease formats: Tested beta, alpha, rc, pre (16/16 scenarios pass)
Benefits
normalized_npm_versionvsclean_npm_version)🤖 Generated with Claude Code
Co-Authored-By: Claude [email protected]
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.