Fix create-react-on-rails-app follow-ups from PR #2375#2571
Fix create-react-on-rails-app follow-ups from PR #2375#2571
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughTrimmed app names are now validated (must start with a letter), Rails version validation requires 7.0+, tests extended for success and failure paths, and related docs and package.json formatting were updated. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
|
Overall the direction is good. Tighter app name validation, composable errors instead of process.exit, cross-platform clean, and the new Rails 7.0+ prerequisite check all improve the package. Test coverage additions are appreciated. Three things worth addressing before merge: (1) execLive is exported but never called anywhere in the codebase - dead code; either remove it or document the use-case, and note why shell:true is needed over the tokenised execLiveArgs. (2) createStepError discards the original stack trace - prefer new Error(message, { cause: error }) (Node 16.9+) so the full chain stays accessible. (3) MIN_RAILS_MINOR and MIN_RUBY_MINOR are both 0, making the minor < MIN_*_MINOR branch always-false dead code; harmless now but could mislead a future maintainer who bumps the minimum. Inline comments posted for all three. |
PR Review: Fix create-react-on-rails-app follow-upsOverall this is a clean, focused PR. The refactors are well-motivated and the test coverage additions are good. A few issues worth addressing: 1. execLive is exported but never used — utils.ts adds execLive(command, cwd) with shell: true, but it is never called. A dead export with shell: true is a latent security risk. Remove it now and add it in the PR that actually needs it, or at minimum leave it unexported until it has a caller. 2. createStepError drops the original stack trace — Constructing a brand-new Error with only the message string discards the original call stack. Node 16.9+ supports the cause option: new Error(message, { cause: error }). This preserves the full stack while still surfacing a user-friendly message. 3. Missing happy-path test for createApp — All three new createApp tests cover failure branches. There is no test verifying that when all execLiveArgs calls succeed the function completes without throwing. A simple fourth case would catch regressions in the success path. 4. Minor: misleading error message for names with leading whitespace — validateAppName(' myapp') returns 'must start with a letter' because the un-trimmed string is compared against the regex after the whitespace guard. Trimming before the regex (or adjusting the guard) would produce a more accurate error. Positives:
|
Greptile SummaryThis PR is a follow-up to #2375, delivering a set of polish and correctness improvements to the Key changes:
Two minor improvements recommended:
Confidence Score: 4/5
Sequence DiagramsequenceDiagram
participant CLI as index.ts (CLI entry)
participant V as validators.ts
participant CA as create-app.ts
participant OS as OS / Shell
CLI->>CA: validateAppName(appName)
note over CA: Regex: /^[a-zA-Z][a-zA-Z0-9_-]*$/
CA-->>CLI: { success, error? }
CLI->>V: validateAll(packageManager)
V->>V: validateNode()
V->>V: validateRuby() — ruby --version, ≥3.0
V->>V: validateRails() — rails --version, ≥7.0 (NEW)
V->>V: validatePackageManager()
V-->>CLI: { allValid, results }
alt allValid
CLI->>CA: createApp(appName, options)
CA->>OS: rails new appName
OS-->>CA: exit 0 (or throws)
CA->>OS: bundle add react_on_rails (in appPath)
OS-->>CA: exit 0 (or throws)
CA->>OS: bundle exec rails generate react_on_rails:install (in appPath)
OS-->>CA: exit 0 (or throws)
CA-->>CLI: (returns)
else not allValid
CLI->>CLI: logError + process.exit(1)
end
note over CLI: Errors thrown by createApp bubble up<br/>to action() catch → logError + exit(1)
Last reviewed commit: cdd0027 |
size-limit report 📦
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
packages/create-react-on-rails-app/tests/validators.test.ts (1)
58-77: Add the exact 7.0 boundary case.These tests cover below-minimum and comfortably above-minimum versions, but not the minimum supported version itself. A
Rails 7.0.xfixture would pin the off-by-one boundary this change introduces.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-react-on-rails-app/tests/validators.test.ts` around lines 58 - 77, Add a test that verifies the boundary case Rails 7.0.x is accepted: in tests/validators.test.ts add a case where mockedGetCommandVersion.mockReturnValue('Rails 7.0.6' or similar 7.0.x) then call validateRails() and assert result.valid === true and result.message includes or equals the version string; reference the existing test pattern using mockedGetCommandVersion and validateRails to mirror the other cases.packages/create-react-on-rails-app/tests/create-app.test.ts (1)
50-58: Consider adding error message assertions for consistency.The test for names starting with a number (line 47) asserts the specific error message. For consistency and better documentation of expected behavior, consider adding similar assertions for the hyphen and underscore cases.
♻️ Suggested improvement
it('rejects names that start with a hyphen', () => { const result = validateAppName('-myapp'); expect(result.success).toBe(false); + expect(result.error).toContain('must start with a letter'); }); it('rejects names that start with an underscore', () => { const result = validateAppName('_myapp'); expect(result.success).toBe(false); + expect(result.error).toContain('must start with a letter'); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-react-on-rails-app/tests/create-app.test.ts` around lines 50 - 58, Add the same error-message assertions to the hyphen and underscore tests as the numeric-start test uses: after calling validateAppName('-myapp') and validateAppName('_myapp'), assert the returned error field (the same property the numeric test checks, e.g. result.error or result.message) equals the expected validation message; this ensures the tests for validateAppName consistently assert both failure and the exact error text.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@analysis/create-react-on-rails-app-proposal.md`:
- Around line 124-129: The doc claims interactive prompt-driven flows and uses a
default `--interactive` behavior but the dependencies block only lists
"commander" and "chalk" (no prompt library); either add a prompt dependency
(e.g., include "inquirer" or "prompts" alongside "commander" in the dependencies
block) and update references to `--interactive` to reflect that the prompt
library will be used, or explicitly mark the prompt-driven sections as "future
work" and remove/qualify the default `--interactive` behavior; ensure you
reference the `--interactive` flag and the dependencies JSON block so reviewers
can verify consistency.
In `@CHANGELOG.md`:
- Line 35: The changelog entry mixes user-facing fixes with internal
implementation and test details; edit the entry for "create-react-on-rails-app
follow-up fixes" so it only lists externally observable changes (e.g., tightened
app name validation must start with a letter, added Rails 7.0+ prerequisite
validation, and CLI setup now surfaces composable errors instead of exiting),
and remove internal-only items such as the `clean` script implementation, test
coverage changes (including `validateAll` success path), and other
refactor/lint/test details; ensure the remaining text is concise and focused on
user-visible behavior and keep references (PR 2571 and author) intact.
In `@docs/getting-started/create-react-on-rails-app.md`:
- Line 63: Update the wording that promises Rails 8 to match the prerequisite
change: replace the line "- **Rails 7.0+** (`gem install rails`)" and any
occurrence of the phrase "A Rails 8 app" in this document with a neutral phrase
such as "Rails 7+" or "the installed Rails version" so the copy remains
accurate; search for the literal strings "A Rails 8 app" and "- **Rails 7.0+**
(`gem install rails`)" and update them accordingly.
In `@packages/create-react-on-rails-app/src/create-app.ts`:
- Around line 43-47: The current regex in validateAppName allows names that
Rails later rejects; update validateAppName to mirror Rails'
AppName#valid_const? checks by (1) computing the CamelCased constant from the
supplied name (split on -/_ and capitalize then join) and ensuring it matches
/^[A-Z]\w*$/ (replace the simple /^[a-zA-Z][a-zA-Z0-9_-]*$/ check), (2)
rejecting names whose CamelCased constant equals or contains reserved class
names like "Rails", "Application" or other Rails reserved constants, and (3)
rejecting Ruby reserved keywords (e.g., def, class, module, begin, end, etc.);
return the same error object when these validations fail so upfront validation
mirrors rails/generators/app_name.rb behavior.
---
Nitpick comments:
In `@packages/create-react-on-rails-app/tests/create-app.test.ts`:
- Around line 50-58: Add the same error-message assertions to the hyphen and
underscore tests as the numeric-start test uses: after calling
validateAppName('-myapp') and validateAppName('_myapp'), assert the returned
error field (the same property the numeric test checks, e.g. result.error or
result.message) equals the expected validation message; this ensures the tests
for validateAppName consistently assert both failure and the exact error text.
In `@packages/create-react-on-rails-app/tests/validators.test.ts`:
- Around line 58-77: Add a test that verifies the boundary case Rails 7.0.x is
accepted: in tests/validators.test.ts add a case where
mockedGetCommandVersion.mockReturnValue('Rails 7.0.6' or similar 7.0.x) then
call validateRails() and assert result.valid === true and result.message
includes or equals the version string; reference the existing test pattern using
mockedGetCommandVersion and validateRails to mirror the other cases.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e7a9fd79-04e2-4c7d-9459-5455d15bfae0
📒 Files selected for processing (9)
CHANGELOG.mdanalysis/create-react-on-rails-app-proposal.mddocs/getting-started/create-react-on-rails-app.mdpackages/create-react-on-rails-app/package.jsonpackages/create-react-on-rails-app/src/create-app.tspackages/create-react-on-rails-app/src/utils.tspackages/create-react-on-rails-app/src/validators.tspackages/create-react-on-rails-app/tests/create-app.test.tspackages/create-react-on-rails-app/tests/validators.test.ts
|
Addressed in commit e058edc:\n\n- removed unused exported \n- preserved wrapped error context by setting \n- simplified the Rails minimum-version check to avoid dead minor-version logic\n- normalized app name handling (trim before validation and use normalized name in orchestration)\n- added a happy-path \ test plus additional validation assertions\n- added an explicit Rails 7.0.x acceptance test\n- updated docs/changelog/proposal wording for consistency\n\nI intentionally kept full Rails \ parity out of this follow-up so this stays scoped to #2383; \Usage: Options: Runtime options: Rails options: Description: Examples: |
|
Addressed in commit e058edc:
I intentionally kept full Rails AppName valid_const parity out of this follow-up so this stays scoped to #2383; rails new remains the authoritative guard for reserved-name collisions. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/create-react-on-rails-app/src/utils.ts (1)
9-24:⚠️ Potential issue | 🟠 MajorBoth functions need Windows-safe process invocation.
On Windows,
npm,pnpm,rails, andbundleare.cmdlaunchers that cannot be executed viaspawnSync()orexecFileSync()withoutshell: true. The current implementation will fail on Windows when detecting package managers indetectPackageManager()(lines 37–38) and when invoking tools inexecLiveArgs(). Use a Windows-safe helper likecross-spawn, or conditionally add{ shell: true }on Windows in bothexecLiveArgs()andgetCommandVersion().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-react-on-rails-app/src/utils.ts` around lines 9 - 24, Windows process launches fail because spawnSync/execFileSync can't run .cmd shims; update execLiveArgs and getCommandVersion to be Windows-safe by either switching to cross-spawn or adding { shell: true } when process.platform === 'win32'. Specifically, modify execLiveArgs (the spawnSync call) to pass shell:true on Windows (or use cross-spawn.sync) and modify getCommandVersion (the execFileSync call) to also use shell:true on Windows (or use cross-spawn to get the version), ensuring stdio/encoding behavior is preserved; this will make detectPackageManager and tool invocations (npm/pnpm/rails/bundle) work on Windows.
♻️ Duplicate comments (1)
packages/create-react-on-rails-app/src/create-app.ts (1)
47-60:⚠️ Potential issue | 🟡 MinorMirror Rails' reserved-name checks in
validateAppName().This still accepts names that
rails newrejects later, such as reserved constants or Ruby keywords, so users can pass validation here and then fail in Step 1 anyway. If this helper is meant to be authoritative, it should mirror Rails' app-name validation rather than only the character pattern.In Rails generators, what names are rejected by Rails::Generators::AppName (for example reserved constants like Rails/Application or Ruby keywords), and how does Rails validate generated app names?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-react-on-rails-app/src/create-app.ts` around lines 47 - 60, validateAppName() currently only checks characters but must mirror Rails::Generators::AppName rules so names rejected by `rails new` are rejected here; update validateAppName() to also reject names that contain Ruby namespace separators ('::'), names that look like Ruby constants (start with an uppercase letter or include uppercase segments like "Rails" or "Application"), known Rails/reserved app names (e.g., "application", "rails", "config", "lib", "test", etc.—create a RESERVED_NAMES array), and Ruby reserved keywords (use a small set or import a canonical list) and return the same failure shape; implement these additional checks inside validateAppName() (add checks for /::/, /^[A-Z]/, membership in RESERVED_NAMES, and membership in RUBY_KEYWORDS) before returning success so validation matches Rails behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/create-react-on-rails-app/src/utils.ts`:
- Around line 9-24: Windows process launches fail because spawnSync/execFileSync
can't run .cmd shims; update execLiveArgs and getCommandVersion to be
Windows-safe by either switching to cross-spawn or adding { shell: true } when
process.platform === 'win32'. Specifically, modify execLiveArgs (the spawnSync
call) to pass shell:true on Windows (or use cross-spawn.sync) and modify
getCommandVersion (the execFileSync call) to also use shell:true on Windows (or
use cross-spawn to get the version), ensuring stdio/encoding behavior is
preserved; this will make detectPackageManager and tool invocations
(npm/pnpm/rails/bundle) work on Windows.
---
Duplicate comments:
In `@packages/create-react-on-rails-app/src/create-app.ts`:
- Around line 47-60: validateAppName() currently only checks characters but must
mirror Rails::Generators::AppName rules so names rejected by `rails new` are
rejected here; update validateAppName() to also reject names that contain Ruby
namespace separators ('::'), names that look like Ruby constants (start with an
uppercase letter or include uppercase segments like "Rails" or "Application"),
known Rails/reserved app names (e.g., "application", "rails", "config", "lib",
"test", etc.—create a RESERVED_NAMES array), and Ruby reserved keywords (use a
small set or import a canonical list) and return the same failure shape;
implement these additional checks inside validateAppName() (add checks for /::/,
/^[A-Z]/, membership in RESERVED_NAMES, and membership in RUBY_KEYWORDS) before
returning success so validation matches Rails behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a38ac26b-4ef1-4be4-bb93-91fc6d5eefc0
📒 Files selected for processing (9)
CHANGELOG.mdanalysis/create-react-on-rails-app-proposal.mddocs/getting-started/create-react-on-rails-app.mdpackages/create-react-on-rails-app/src/create-app.tspackages/create-react-on-rails-app/src/index.tspackages/create-react-on-rails-app/src/utils.tspackages/create-react-on-rails-app/src/validators.tspackages/create-react-on-rails-app/tests/create-app.test.tspackages/create-react-on-rails-app/tests/validators.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/create-react-on-rails-app/tests/validators.test.ts
- docs/getting-started/create-react-on-rails-app.md
- analysis/create-react-on-rails-app-proposal.md
e058edc to
cac8976
Compare
| it('rejects names that start with a number', () => { | ||
| const result = validateAppName('123app'); | ||
| expect(result.success).toBe(false); | ||
| expect(result.error).toContain('must start with a letter'); | ||
| }); |
There was a problem hiding this comment.
This test is a near-duplicate of the existing 'rejects names starting with a digit' case on line 65 (which tests '1app'). Both inputs follow the same code path and assert the same error substring. Consider removing one to keep the suite non-redundant.
| if (!name || name.trim() === '') { | ||
| const trimmedName = name.trim(); | ||
|
|
||
| if (!name || trimmedName === '') { |
There was a problem hiding this comment.
Since name is typed as string, !name is only ever true when name === '', which is already subsumed by trimmedName === ''. The condition can be simplified:
| if (!name || trimmedName === '') { | |
| if (!trimmedName) { |
| success: false, | ||
| error: | ||
| 'App name must start with a letter, end with a letter or number, and may contain hyphens or underscores only between alphanumeric characters.', | ||
| }; |
There was a problem hiding this comment.
This single error message is returned for every regex failure, including names like 'my app' (which does start with a letter but contains a space). The test on line 50 of the test file asserts .toContain('must start with a letter') for the 'my app' case, which passes today only because the message happens to contain that phrase — but the wording is misleading for that input.
Consider a more general message such as:
'App name must start with a letter and may only contain letters, numbers, hyphens, or underscores (no spaces or special characters).'
or keep the current message but add a note about disallowed characters so it's accurate for all failure modes.
| const packageJson = require('../package.json') as { version: string }; | ||
|
|
||
| function run(appName: string, rawOpts: Record<string, unknown>): void { | ||
| const normalizedAppName = appName.trim(); |
There was a problem hiding this comment.
validateAppName already trims the name internally (line 87 of create-app.ts), so the trim here and the one inside the function are redundant. They're harmless, but if validateAppName is meant to be an exported/reusable helper that handles normalization internally, consider either: (a) relying solely on the internal trim and removing this one, or (b) having validateAppName accept only an already-normalized name and moving the trim responsibility entirely to the caller. Either way, the API contract should be clear.
|
|
||
| ### [Unreleased] | ||
|
|
||
| Changes since the last non-beta release. |
There was a problem hiding this comment.
The line Changes since the last non-beta release. appears to have been accidentally inserted here. It doesn't match the established CHANGELOG format used by other release sections in this file and adds no actionable information.
| Changes since the last non-beta release. |
Review SummaryThe changes are generally clean and well-tested. A few minor issues worth addressing: Bug-free / no security concerns — the app name validation, Rails 7.0+ enforcement, and trimming logic are all correct. Nits / minor issues (inline comments posted)
|
| After completion, you get: | ||
|
|
||
| - A Rails app with PostgreSQL (Rails 7+) | ||
| - A Rails 7+ app with PostgreSQL |
There was a problem hiding this comment.
should be current version of Rails listed and indicate to use the most current for a new app
PR Review: Fix create-react-on-rails-app follow-upsOverall these are clean, focused improvements. Trimming behavior, stricter regex enforcement, and Rails 7.0+ validation are all solid. Test coverage expansion is good. A few minor issues below. 1. Redundant null-check in validateAppName
2. Duplicate digit-start test case create-app.test.ts now has two nearly identical tests: one testing 3. Missing test for leading/trailing whitespace trimming
|
| if (!name || name.trim() === '') { | ||
| const trimmedName = name.trim(); | ||
|
|
||
| if (!name || trimmedName === '') { |
There was a problem hiding this comment.
The !name check is redundant here. Since name.trim() was already called on line 87 without throwing, name is guaranteed to be a non-null string. The only additional case !name covers beyond trimmedName === '' is name === '', but ''.trim() === '', so trimmedName === '' already handles that. Consider simplifying:
| if (!name || trimmedName === '') { | |
| if (trimmedName === '') { |
| expect(result.success).toBe(false); | ||
| }); | ||
|
|
||
| it('rejects names that start with a number', () => { |
There was a problem hiding this comment.
This test is a near-duplicate of the existing 'rejects names starting with a digit' test above (which tests '1app'). Both exercise the same regex branch and the same error message. One of them should be removed to avoid redundancy.
| const result = validateAppName('123app'); | ||
| expect(result.success).toBe(false); | ||
| expect(result.error).toContain('must start with a letter'); | ||
| }); |
There was a problem hiding this comment.
The PR adds internal trimming to validateAppName, but there is no test that exercises this path directly. Consider adding a test after the digit-start tests:
it('accepts names with leading/trailing whitespace after trimming', () => {
const result = validateAppName(' myapp ');
expect(result.success).toBe(true);
});This would guard against a regression if the name.trim() call were accidentally removed.
…e double trim - Move null check before .trim() in validateAppName to prevent TypeError on null/undefined input from JS callers - Simplify empty-string guard to just check !trimmedName (falsy covers it) - Remove redundant .trim() in index.ts since validateAppName trims internally; also remove the now-pointless normalizedAppName alias - Remove duplicate "rejects names that start with a number" test (123app) since "rejects names starting with a digit" (1app) already covers the case Co-Authored-By: Claude Opus 4.6 <[email protected]>
| } | ||
|
|
||
| if (!/^[a-zA-Z][a-zA-Z0-9]*([_-][a-zA-Z0-9]+)*$/.test(name)) { | ||
| const trimmedName = name.trim(); |
There was a problem hiding this comment.
Trimmed name is validated but not propagated to the caller.
validateAppName now validates against trimmedName internally, but still returns only { success: true } — not the trimmed value. In index.ts, the caller passes the original appName to createApp:
// index.ts
const nameValidation = validateAppName(appName); // validates trimmed internally
// ...
createApp(appName, options); // uses original, untrimmed!Before this PR, a name like " myapp " (surrounding spaces) would have been rejected at the regex check because the raw string starts with a space. After this PR, .trim() causes it to pass validation, but createApp still receives the space-padded string and would call rails new " myapp ", which fails or produces an unexpected directory.
Suggested fix: either return the trimmed name from this function (e.g., { success: true, name: trimmedName }) and use it in the caller, or trim appName in index.ts before both calls.
|
Overall this is a clean, focused set of follow-up fixes. The validation tightening and test additions are well done. One functional issue and a couple of minor observations below. Bug: trimmed name not propagated to createApp The main issue is in validateAppName: it validates against trimmedName internally but returns success:true without the trimmed value. The caller in index.ts then passes the original appName (untrimmed) to createApp (see inline comment). Before this PR, a whitespace-padded input would have been rejected by the regex since the raw string starts with a space. After this PR it silently passes validation, but createApp still receives the space-padded string and would call rails new with it. Fix: return the trimmed name from validateAppName (e.g. return { success: true, name: trimmedName }), or trim appName in index.ts before both calls. Minor observations Two tests for Rails 6.1: validators.test.ts now has both 'returns invalid for Rails 6.1' (new, 6.1.7.10) and 'returns invalid for Rails 6.x' (existing, 6.1.7). The new one is better since it asserts message wording, but they cover the same code path and are largely redundant. Redundant null guard: the first if (!name) handles null/undefined/empty-string, and the second if (!trimmedName) handles whitespace-only. The original single expression was equivalent and more concise. What is good Stricter regex applied to trimmedName is the right call. Test assertions on error message wording are a solid improvement over bare false checks. The new Rails 7.0.x test with a four-part version string (7.0.8.7) adds genuine coverage for a format the previous tests missed. Docs and proposal cleanup are clear and accurate. |
## Summary - enforce stricter app name validation so generated project names must start with a letter - require Rails 7.0+ for generated apps - replace in-helper process exits with composable thrown errors - simplify generator args construction and improve command execution utility/docs - update tests and docs for these follow-up fixes Fixes #2383. ## Manual testing - pnpm --filter create-react-on-rails-app test - pnpm --filter create-react-on-rails-app type-check - pnpm exec eslint packages/create-react-on-rails-app/src/**/*.ts - pnpm exec prettier --check packages/create-react-on-rails-app/src/**/*.ts packages/create-react-on-rails-app/tests/**/*.ts - smoke: invalid app name run (`node packages/create-react-on-rails-app/lib/index.js 123bad`) fails with validation error - smoke: full app generation run (`node packages/create-react-on-rails-app/lib/index.js smokeapp --template javascript --package-manager npm`) succeeds <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Tightened app-name validation: names must start with a letter and leading/trailing whitespace is trimmed. * Added explicit Rails 7.0+ prerequisite validation. * **Documentation** * Updated minimum Rails guidance to "Rails 7.0+" and recommended using the most current Rails version. * Clarified option descriptions and completion list (adds server-side rendering readiness and development scripts). * **Tests** * Added and expanded tests for name validation and Rails version checks. * **Chores** * Updated changelog entry. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
## Summary - enforce stricter app name validation so generated project names must start with a letter - require Rails 7.0+ for generated apps - replace in-helper process exits with composable thrown errors - simplify generator args construction and improve command execution utility/docs - update tests and docs for these follow-up fixes Fixes #2383. ## Manual testing - pnpm --filter create-react-on-rails-app test - pnpm --filter create-react-on-rails-app type-check - pnpm exec eslint packages/create-react-on-rails-app/src/**/*.ts - pnpm exec prettier --check packages/create-react-on-rails-app/src/**/*.ts packages/create-react-on-rails-app/tests/**/*.ts - smoke: invalid app name run (`node packages/create-react-on-rails-app/lib/index.js 123bad`) fails with validation error - smoke: full app generation run (`node packages/create-react-on-rails-app/lib/index.js smokeapp --template javascript --package-manager npm`) succeeds <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Tightened app-name validation: names must start with a letter and leading/trailing whitespace is trimmed. * Added explicit Rails 7.0+ prerequisite validation. * **Documentation** * Updated minimum Rails guidance to "Rails 7.0+" and recommended using the most current Rails version. * Clarified option descriptions and completion list (adds server-side rendering readiness and development scripts). * **Tests** * Added and expanded tests for name validation and Rails version checks. * **Chores** * Updated changelog entry. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
Summary
Fixes #2383.
Manual testing
node packages/create-react-on-rails-app/lib/index.js 123bad) fails with validation errornode packages/create-react-on-rails-app/lib/index.js smokeapp --template javascript --package-manager npm) succeedsSummary by CodeRabbit
Bug Fixes
Documentation
Tests
Chores