Skip to content

Make rails new with core_setup run unattended and produce a working app - #215

Merged
OutlawAndy merged 11 commits into
masterfrom
smooth-new-app
Oct 14, 2026
Merged

OutlawAndy merged 11 commits into
masterfrom
smooth-new-app

Conversation

@OutlawAndy

@OutlawAndy OutlawAndy commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Why?

Generating a new app with rails new --template (which runs rolemodel:core_setup --material) hung, and then produced an app that wouldn't build or boot. Every cause traced back to this gem. Several generators also failed partway while still exiting 0, so the damage was easy to miss.

What Changed

  • Package dotfile templates.
    • Dir['lib/**/*'] skips dotfiles, so the published gem had no .rubocop.yml, .rubocop/cops, .rspec, or .rspec_parallel. The generators that copy them raised partway. For example, testing:parallel_tests never reached its database.yml TEST_ENV_NUMBER edit, so every parallel process shared one test database.
  • Remove the Copilot instructions from the github generator. Its instructions symlink pointed outside the gem and didn't survive installation, so the generator raised partway. The instructions were stale, so rather than package them, the generator no longer installs .github/instructions, and the instructions and symlink are deleted.
  • Keep package.json when setting up Yarn. Yarn 4's yarn init replaces an existing package.json with only name and packageManager. The webpack generator triggers Yarn setup after Rails has written package.json, so new apps lost the build script, type: module, and the Hotwire packages. yarn set version stable already pins packageManager, so yarn init now runs only when there is no package.json.
  • Add strip-sourcemap-loader to the webpack generator's dev dependencies. webpack.config.js uses it.
  • Drop config.enable_logs from the Sentry initializer. sentry-ruby 7 removed it, since structured logging is now on by default, so the generated app raised NoMethodError at boot.
  • Stop the icon library prompt from hanging. With no terminal attached, as in a rails new template, Thor's limited_to prompt treats end of input as a wrong answer and loops forever at 100% CPU.
    • New GeneratorBase#ask_or_default prompts only when stdin is a terminal and otherwise returns the default. optics:icons uses it, so it installs material when nobody can answer.
    • core_setup and optics:all now accept the icons generator's flags (--material, --phosphor, …) and pass them to optics:icons, so a template can still choose a non-default library.
  • Replace the Rails README without prompting (force: true).
  • Honor --pretend when setting up Yarn. ensure_yarn invoked yarn:setup with empty options, which dropped --pretend. Yarn#yes! also ran commands through Open3 directly. So a pretend run still pinned Yarn and wrote .yarnrc.yml, package.json, and .gitignore.
  • Restore .rspec from the rspec generator. Change the testing:all prompt to a class option flag (off by default) #195 dropped the copy.
  • deploy-app skill preflight:
    • Offers to create the GitHub repo when a brand-new app has no origin, with gh auth now checked first.
    • Drops two stale readiness checks:
      • The webpack config no longer imports terser-webpack-plugin.
      • Rails merges DATABASE_URL into the primary database config without a url: key.

Pre-merge checklist

  • Update relevant READMEs (core_setup, optics, github)

Notes

How this was verified:

  • Specs. Every fix has a spec that failed first. Full suite: 117 examples, 0 failures.
  • Fresh app. A clean rails new … --template against this branch, with stdin from /dev/null, finished unattended. The generated app:
    • has .rspec, .rspec_parallel, .rubocop.yml, .rubocop/cops, and the github generator's workflows and PR template
    • keeps its build script, type: module, and the Hotwire packages
    • passes yarn build, zeitwerk:check, and rspec
  • Packaging. Built the gem and inspected the archive: the dotfiles are packaged, it contains no symlinks, and nothing else new came along.

Not in this PR: a freshly generated app still fails its own rubocop. Most offenses are in Rails-generated files (quotes, frozen string literals). The rest are Bundler/DuplicatedGroup, because gem_group appends a new block on every call. Fixing that takes a final rubocop -A in core_setup plus gem_group consolidation, which would also make deploy-app's Gemfile-cleanup phase unnecessary. Proposing that separately.

Please don't commit version changes within your PR. Versioning, releasing, and changelog entries are managed through the Release workflow.

Screenshots

N/A — no UI changes

🤖 Generated with Claude Code

@OutlawAndy
OutlawAndy requested a review from wesrich October 14, 2026 17:28
OutlawAndy and others added 11 commits October 14, 2026 13:02
Dir['lib/**/*'] skips dotfiles, so the published gem had no .rubocop.yml,
.rubocop/cops, .rspec, or .rspec_parallel. The generators that copy them
raised partway, skipping later steps such as the parallel_tests
database.yml edit, while still exiting successfully. The github
generator's instructions symlink pointed outside the gem and did not
survive installation; it now copies from the packaged .github/instructions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yarn 4's yarn init replaces an existing package.json with only name and
packageManager. The webpack generator triggers Yarn setup after Rails has
written package.json, so new apps lost the build script, type: module,
and the Hotwire packages. yarn set version already pins packageManager.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
sentry-ruby 7 removed the option (structured logging is on by default),
so the generated initializer raised NoMethodError at boot.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
core_setup and optics:all did not accept --material and friends, so the
icons generator always prompted. Run without a terminal (e.g. from a
rails new template) the prompt's limited_to loop spins forever on EOF.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The copy was dropped in #195, leaving the template unused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Offer to create the GitHub repo when there is no origin. Drop two stale
readiness checks: the webpack config no longer imports
terser-webpack-plugin, and Rails merges DATABASE_URL into the primary
config without a url: key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Thor's ask with limited_to loops forever on EOF, so running optics:icons
without a terminal (e.g. from a rails new template) hung. ask_or_default
on GeneratorBase only prompts when stdin is a TTY.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ensure_yarn invoked yarn:setup with empty options, dropping --pretend, and
Yarn#yes! shelled out through Open3 directly, so a pretend run still pinned
Yarn and wrote .yarnrc.yml, package.json, and .gitignore.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@OutlawAndy OutlawAndy self-assigned this Oct 14, 2026
@wesrich

wesrich commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Heads up, the PR description is now out of date: it says the .github/instructions symlink issue was fixed by having the generator copy from the packaged .github/instructions dir, and the verification notes list .github/instructions as present in the generated app. But the later "remove stale instructions" commit (3accbd5) actually deletes the Copilot instructions feature entirely rather than packaging it. Worth updating the description before merge so it matches what's actually shipping.

@OutlawAndy
OutlawAndy merged commit d50f01c into master Oct 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants