mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix backwards compatibility with Rails 3 apps.
When we removed script/rails and introduced bin/rails, we accidentally introduced a regression. If you install Rails 4 as a gem, then try to do something in a Rails 3 application: $ rails g This will throw the 'please type rails new foo' message rather than the proper generator documentation message. This is because older apps don't have bin/rails. Therefore, we now *prefer* bin/rails, but still search for script/rails, and exec the one we find.
This commit is contained in:
parent
31f807c7aa
commit
c5a9c02e01
3 changed files with 52 additions and 40 deletions
|
@ -3,12 +3,16 @@ require 'pathname'
|
|||
module Rails
|
||||
module AppRailsLoader
|
||||
RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
|
||||
EXECUTABLE = 'bin/rails'
|
||||
EXECUTABLES = ['bin/rails', 'script/rails']
|
||||
|
||||
def self.exec_app_rails
|
||||
cwd = Dir.pwd
|
||||
return unless in_rails_application_or_engine? || in_rails_application_or_engine_subdirectory?
|
||||
exec RUBY, EXECUTABLE, *ARGV if in_rails_application_or_engine?
|
||||
cwd = Dir.pwd
|
||||
|
||||
exe = find_executable
|
||||
exe ||= find_executable_in_parent_path
|
||||
return unless exe
|
||||
|
||||
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.
|
||||
|
@ -18,12 +22,16 @@ module Rails
|
|||
# could not chdir, no problem just return
|
||||
end
|
||||
|
||||
def self.in_rails_application_or_engine?
|
||||
File.exists?(EXECUTABLE) && File.read(EXECUTABLE) =~ /(APP|ENGINE)_PATH/
|
||||
def self.find_executable
|
||||
EXECUTABLES.find do |exe|
|
||||
File.exists?(exe) && File.read(exe) =~ /(APP|ENGINE)_PATH/
|
||||
end
|
||||
end
|
||||
|
||||
def self.in_rails_application_or_engine_subdirectory?(path = Pathname.new(Dir.pwd))
|
||||
File.exists?(File.join(path, EXECUTABLE)) || !path.root? && in_rails_application_or_engine_subdirectory?(path.parent)
|
||||
def self.find_executable_in_parent_path(path = Pathname.new(Dir.pwd))
|
||||
EXECUTABLES.find do |exe|
|
||||
File.exists?(File.join(path, exe)) || !path.root? && find_executable_in_parent_path(path.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,9 +3,6 @@ require 'rails/app_rails_loader'
|
|||
|
||||
# If we are inside a Rails application this method performs an exec and thus
|
||||
# the rest of this script is not run.
|
||||
#
|
||||
# TODO: when we hit this, advise adding ./bin to $PATH instead. Then the
|
||||
# app's `rails` executable is run immediately.
|
||||
Rails::AppRailsLoader.exec_app_rails
|
||||
|
||||
require 'rails/ruby_version_check'
|
||||
|
|
|
@ -2,40 +2,47 @@ require 'abstract_unit'
|
|||
require 'rails/app_rails_loader'
|
||||
|
||||
class AppRailsLoaderTest < ActiveSupport::TestCase
|
||||
test "is in a rails application if bin/rails exists and contains APP_PATH" do
|
||||
File.stubs(:exists?).returns(true)
|
||||
File.stubs(:read).with('bin/rails').returns('APP_PATH')
|
||||
assert Rails::AppRailsLoader.in_rails_application_or_engine?
|
||||
|
||||
setup do
|
||||
File.stubs(:exists?).returns(false)
|
||||
end
|
||||
|
||||
test "is not in a rails application if bin/rails exists but doesn't contain APP_PATH" do
|
||||
File.stubs(:exists?).returns(true)
|
||||
File.stubs(:read).with('bin/rails').returns('railties bin/rails')
|
||||
assert !Rails::AppRailsLoader.in_rails_application_or_engine?
|
||||
end
|
||||
['bin/rails', 'script/rails'].each do |exe|
|
||||
test "is in a rails application if #{exe} exists and contains APP_PATH" do
|
||||
File.stubs(:exists?).with(exe).returns(true)
|
||||
File.stubs(:read).with(exe).returns('APP_PATH')
|
||||
assert Rails::AppRailsLoader.find_executable
|
||||
end
|
||||
|
||||
test "is in a rails application if parent directory has bin/rails containing APP_PATH" do
|
||||
File.stubs(:exists?).with("/foo/bar/bin/rails").returns(false)
|
||||
File.stubs(:exists?).with("/foo/bin/rails").returns(true)
|
||||
File.stubs(:read).with('/foo/bin/rails').returns('APP_PATH')
|
||||
assert Rails::AppRailsLoader.in_rails_application_or_engine_subdirectory?(Pathname.new("/foo/bar"))
|
||||
end
|
||||
test "is not in a rails application if #{exe} exists but doesn't contain APP_PATH" do
|
||||
File.stubs(:exists?).with(exe).returns(true)
|
||||
File.stubs(:read).with(exe).returns("railties #{exe}")
|
||||
assert !Rails::AppRailsLoader.find_executable
|
||||
end
|
||||
|
||||
test "is not in a rails application if at the root directory and doesn't have bin/rails" do
|
||||
Pathname.any_instance.stubs(:root?).returns true
|
||||
assert !Rails::AppRailsLoader.in_rails_application_or_engine?
|
||||
end
|
||||
test "is in a rails application if parent directory has #{exe} containing APP_PATH" do
|
||||
File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false)
|
||||
File.stubs(:exists?).with("/foo/#{exe}").returns(true)
|
||||
File.stubs(:read).with("/foo/#{exe}").returns('APP_PATH')
|
||||
assert Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar"))
|
||||
end
|
||||
|
||||
test "is in a rails engine if parent directory has bin/rails containing ENGINE_PATH" do
|
||||
File.stubs(:exists?).with("/foo/bar/bin/rails").returns(false)
|
||||
File.stubs(:exists?).with("/foo/bin/rails").returns(true)
|
||||
File.stubs(:read).with('/foo/bin/rails').returns('ENGINE_PATH')
|
||||
assert Rails::AppRailsLoader.in_rails_application_or_engine_subdirectory?(Pathname.new("/foo/bar"))
|
||||
end
|
||||
test "is not in a rails application if at the root directory and doesn't have #{exe}" do
|
||||
Pathname.any_instance.stubs(:root?).returns true
|
||||
assert !Rails::AppRailsLoader.find_executable
|
||||
end
|
||||
|
||||
test "is in a rails engine if bin/rails exists containing ENGINE_PATH" do
|
||||
File.stubs(:exists?).returns(true)
|
||||
File.stubs(:read).with('bin/rails').returns('ENGINE_PATH')
|
||||
assert Rails::AppRailsLoader.in_rails_application_or_engine?
|
||||
test "is in a rails engine if parent directory has #{exe} containing ENGINE_PATH" do
|
||||
File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false)
|
||||
File.stubs(:exists?).with("/foo/#{exe}").returns(true)
|
||||
File.stubs(:read).with("/foo/#{exe}").returns('ENGINE_PATH')
|
||||
assert Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar"))
|
||||
end
|
||||
|
||||
test "is in a rails engine if #{exe} exists containing ENGINE_PATH" do
|
||||
File.stubs(:exists?).with(exe).returns(true)
|
||||
File.stubs(:read).with(exe).returns('ENGINE_PATH')
|
||||
assert Rails::AppRailsLoader.find_executable
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue