Skip to content
Browse files

Explain how to upgrade bin/ for Rails 4

  • Loading branch information...
1 parent 74be6bb commit 9039c5038823754f79e04f1e83723e46229dbe05 @jeremy jeremy committed Apr 9, 2013
Showing with 29 additions and 8 deletions.
  1. +29 −8 railties/lib/rails/app_rails_loader.rb
37 railties/lib/rails/app_rails_loader.rb
@@ -12,22 +12,43 @@ def self.exec_app_rails
exe ||= find_executable_in_parent_path
return unless exe
- if =~ /(APP|ENGINE)_PATH/
- # This is a Rails-generated binstub, let's use it
+ contents =
+ # This is the Rails executable, let's use it
+ if contents =~ /(APP|ENGINE)_PATH/
exec RUBY, exe, *ARGV if find_executable
Dir.chdir("..") do
# Recurse in a chdir block: if the search fails we want to be sure
# the application is generated in the original working directory.
exec_app_rails unless cwd == Dir.pwd
- elsif exe.match(%r(bin/rails$))
- # this is a Bundler binstub, so we load the app ourselves
+ # This is a Bundler binstub. Stop and explain how to upgrade.
+ elsif exe =~ /bin\/rails$/ && contents =~ /This file was generated by Bundler/
+ $stderr.puts <<-end_bin_upgrade_warning
Ruby on Rails member
steveklabnik added a note Apr 9, 2013

is strip_heredoc appropriate here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+Looks like your app's ./bin/rails is a stub that was generated by Bundler.
+In Rails 4, your app's bin/ directory contains executables that are versioned
+like any other source code, rather than stubs that are generated on demand.
+Here's how to upgrade:
+ bundle config --delete bin # Turn off Bundler's stub generator
+ rake rails:update:bin # Use the new Rails 4 executables
+ git add bin # Add bin/ to source control
+You may need to remove bin/ from your .gitignore as well.
+When you install a gem whose executable you want to use in your app,
+generate it and add it to source control:
+ bundle binstubs some-gem-name
+ git add bin/new-executable
+ end_bin_upgrade_warning
Object.const_set(:APP_PATH, File.expand_path('config/application', Dir.pwd))
require File.expand_path('../boot', APP_PATH)
- puts "Rails 4 no longer supports Bundler's --binstubs option. You " \
- "will need to disable it and update your bin/rails file.\n" \
- "Please run: `bundle config --delete bin && rm -rf bin`, then " \
- "`rake rails:update:bin` and add the resulting bin/ to git."
require 'rails/commands'
rescue SystemCallError

4 comments on commit 9039c50

Ruby on Rails member
fxn commented on 9039c50 Apr 9, 2013


Ruby on Rails member
mislav commented on 9039c50 Apr 11, 2013

Can somebody point me to a technical reason why bin/rails doesn't work if generated by Bundler?

agis- commented on 9039c50 Apr 11, 2013

@mislav I think 22e5ab3 is relevant

Ruby on Rails member
jeremy commented on 9039c50 Apr 11, 2013

@mislav it's due to the way rails behavior changes depending on whether you're inside a Rails app or outside it.

If you're inside an app, we exec bin/rails and let it handle the in-app rails commands. If you're outside an app, we provide the rails new command to generate apps.

When Bundler overwrites bin/rails with a gem stub, execing the stub will exec the rails executable in the Rails gem. But the rails executable is what just execed bin/rails! Boom.

The major change here is that Rails 4 is treating bin/ as part of your app's source code. This philosophy is at odds with Bundler, which treats bin/ as an ephemeral directory whose contents can be overwritten. Future Bundler (probably 2.0 due to semver constraints) will prompt rather than overwrite and, hopefully, won't treat --binstubs as a sticky option.

Please sign in to comment.
Something went wrong with that request. Please try again.