aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2013-02-22 14:09:43 -0500
committerSteve Klabnik <steve@steveklabnik.com>2013-02-22 14:30:21 -0500
commitc5a9c02e01040831f7e00d3dfa0cfe423f7eb1f9 (patch)
tree02440fd4138684d5af38c7a12ff5e44f14183746 /railties
parent31f807c7aaaf12c16ea1572559c00f49d54d6f43 (diff)
downloadrails-c5a9c02e01040831f7e00d3dfa0cfe423f7eb1f9.tar.gz
rails-c5a9c02e01040831f7e00d3dfa0cfe423f7eb1f9.tar.bz2
rails-c5a9c02e01040831f7e00d3dfa0cfe423f7eb1f9.zip
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.
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/app_rails_loader.rb24
-rw-r--r--railties/lib/rails/cli.rb3
-rw-r--r--railties/test/app_rails_loader_test.rb65
3 files changed, 52 insertions, 40 deletions
diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb
index 8937e10db3..44f4d3dabc 100644
--- a/railties/lib/rails/app_rails_loader.rb
+++ b/railties/lib/rails/app_rails_loader.rb
@@ -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
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index b717b026de..e5341ac436 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -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'
diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb
index 87e0ad7bd7..63ed9eaef0 100644
--- a/railties/test/app_rails_loader_test.rb
+++ b/railties/test/app_rails_loader_test.rb
@@ -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?
- 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?
+ setup do
+ File.stubs(:exists?).returns(false)
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
+ ['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 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 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 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 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 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 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 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 #{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