aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/app_rails_loader.rb
blob: aae628290df321438e811aa3965311b241be5d2b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
require 'pathname'

module Rails
  module AppRailsLoader
    RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
    EXECUTABLES = ['bin/rails', 'script/rails']

    def self.exec_app_rails
      original_cwd = Dir.pwd

      until exe = find_executable
        # If we exhaust the search there is no executable, this could be a
        # call to generate a new application, so restore the original cwd.
        Dir.chdir(original_cwd) and return if Pathname.new(Dir.pwd).root?

        # Otherwise keep moving upwards in search of a executable.
        Dir.chdir('..')
      end

      contents = File.read(exe)

      # This is the Rails executable, let's use it
      if contents =~ /(APP|ENGINE)_PATH/
        exec RUBY, exe, *ARGV

      # 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
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)
        require 'rails/commands'
      end
    rescue SystemCallError
      # could not chdir, no problem just return
    end

    def self.find_executable
      EXECUTABLES.find { |exe| File.exists?(exe) }
    end
  end
end