Skip to content

Commit

Permalink
Add enhanced default bin/dev
Browse files Browse the repository at this point in the history
Fixes rails#52459

The current default `bin/dev` execs the Rails server directly and
doesn't support Procfiles. Therefore, gems like `jsbundling-rails`,
`tailwindcss-rails`, and soon `solid_queue` need to overwrite the
`bin/dev` script with their own version.

With this new version, gems can skip overwriting the `bin/dev` script
and add to the Procfile instead.

It spawns Foreman in the background to allow breakpoints in the Rails
process without Foreman eating the inputs or interleaving its output.
  • Loading branch information
JoeDupuis committed Jan 7, 2025
1 parent ba468db commit c6019f3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
8 changes: 8 additions & 0 deletions railties/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
* Enhanced `bin/dev` Script

Previously, `bin/dev` would only start the Rails server. Gems requiring multiple processes override the `bin/dev` script to start Foreman instead, which prevents interaction with the Rails server console (debugger).

This new `bin/dev` script starts Foreman in the background if a `Procfile.dev` is present and starts Rails in the foreground to allow debugging with breakpoints.

*Joé Dupuis*

## Rails 8.0.0.beta1 (September 26, 2024) ##

* Exit `rails g` with code 1 if generator could not be found.
Expand Down
38 changes: 37 additions & 1 deletion railties/lib/rails/generators/rails/app/templates/bin/dev.tt
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
exec "./bin/rails", "server", *ARGV
ENV["PORT"] ||= "3000"
VERBOSE = ARGV.include?("--verbose") || ARGV.include?("-v") || ENV["VERBOSE"]
RAILS_ARGS = ARGV - [ "--verbose", "-v" ]
PROCFILE = "Procfile.dev"
Process.exec(*%w[bundle exec rails server], *RAILS_ARGS) unless File.exist?(PROCFILE)

Signal.trap("INT") { }

if system(*%w[gem list --no-installed --exact --silent foreman])
puts "Installing foreman..."
system(*%w[gem install foreman])
end

begin
in_r, in_w = IO.pipe
in_w.close
foreman_pid = Process.spawn(
*%w[foreman start -f Procfile.dev -m all=1,web=0 --env /dev/null],
in: in_r,
out: (VERBOSE ? STDOUT : "/dev/null"),
err: (VERBOSE ? STDOUT : "/dev/null"),
pgroup: true,
)
foreman_pgid = Process.getpgid(foreman_pid)
pid = Process.spawn(*%w[bundle exec rails server], *RAILS_ARGS)

Process.wait(pid)
pid = nil
ensure
Process.kill("INT", -foreman_pgid)
Process.wait(-foreman_pgid)
begin
Process.kill("KILL", pid) if pid
rescue Errno::ESRCH
end
in_r.close
end

0 comments on commit c6019f3

Please sign in to comment.