Skip to content
This repository
Browse code

Explain how to upgrade bin/ for Rails 4

  • Loading branch information...
commit 9039c5038823754f79e04f1e83723e46229dbe05 1 parent 74be6bb
Jeremy Kemper jeremy authored

Showing 1 changed file with 29 additions and 8 deletions. Show diff stats Hide diff stats

  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
12 12 exe ||= find_executable_in_parent_path
13 13 return unless exe
14 14
15   - if File.read(exe) =~ /(APP|ENGINE)_PATH/
16   - # This is a Rails-generated binstub, let's use it
  15 + contents = File.read(exe)
  16 +
  17 + # This is the Rails executable, let's use it
  18 + if contents =~ /(APP|ENGINE)_PATH/
17 19 exec RUBY, exe, *ARGV if find_executable
18 20 Dir.chdir("..") do
19 21 # Recurse in a chdir block: if the search fails we want to be sure
20 22 # the application is generated in the original working directory.
21 23 exec_app_rails unless cwd == Dir.pwd
22 24 end
23   - elsif exe.match(%r(bin/rails$))
24   - # this is a Bundler binstub, so we load the app ourselves
  25 +
  26 + # This is a Bundler binstub. Stop and explain how to upgrade.
  27 + elsif exe =~ /bin\/rails$/ && contents =~ /This file was generated by Bundler/
  28 + $stderr.puts <<-end_bin_upgrade_warning
  29 +Looks like your app's ./bin/rails is a stub that was generated by Bundler.
  30 +
  31 +In Rails 4, your app's bin/ directory contains executables that are versioned
  32 +like any other source code, rather than stubs that are generated on demand.
  33 +
  34 +Here's how to upgrade:
  35 +
  36 + bundle config --delete bin # Turn off Bundler's stub generator
  37 + rake rails:update:bin # Use the new Rails 4 executables
  38 + git add bin # Add bin/ to source control
  39 +
  40 +You may need to remove bin/ from your .gitignore as well.
  41 +
  42 +When you install a gem whose executable you want to use in your app,
  43 +generate it and add it to source control:
  44 +
  45 + bundle binstubs some-gem-name
  46 + git add bin/new-executable
  47 +
  48 + end_bin_upgrade_warning
  49 +
25 50 Object.const_set(:APP_PATH, File.expand_path('config/application', Dir.pwd))
26 51 require File.expand_path('../boot', APP_PATH)
27   - puts "Rails 4 no longer supports Bundler's --binstubs option. You " \
28   - "will need to disable it and update your bin/rails file.\n" \
29   - "Please run: `bundle config --delete bin && rm -rf bin`, then " \
30   - "`rake rails:update:bin` and add the resulting bin/ to git."
31 52 require 'rails/commands'
32 53 end
33 54 rescue SystemCallError

4 comments on commit 9039c50

Steve Klabnik

is strip_heredoc appropriate here?

Xavier Noria
Owner
fxn commented on 9039c50

:heart:

Mislav Marohnić

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

Agis Anastasopoulos

@mislav I think 22e5ab3 is relevant

Jeremy Kemper
Owner

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