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
View
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 File.read(exe) =~ /(APP|ENGINE)_PATH/
- # This is a Rails-generated binstub, let's use it
+ contents = File.read(exe)
+
+ # 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
end
- 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
@steveklabnik
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'
end
rescue SystemCallError

4 comments on commit 9039c50

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

❤️

@mislav
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-
agis- commented on 9039c50 Apr 11, 2013

@mislav I think 22e5ab3 is relevant

@jeremy
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.