diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index d54120f850..a0e5d6a5a5 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -18,6 +18,10 @@ module Rails @plugin_loader ||= config.plugin_loader.new(self) end + def root + config.root + end + def routes ActionController::Routing::Routes end @@ -102,7 +106,7 @@ module Rails # Create tmp directories initializer :ensure_tmp_directories_exist do %w(cache pids sessions sockets).each do |dir_to_make| - FileUtils.mkdir_p(File.join(config.root_path, 'tmp', dir_to_make)) + FileUtils.mkdir_p(File.join(config.root, 'tmp', dir_to_make)) end end @@ -346,7 +350,7 @@ module Rails # Loads all plugins in config.plugin_paths. plugin_paths # defaults to vendor/plugins but may also be set to a list of # paths, such as - # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"] + # config.plugin_paths = ["#{config.root}/lib/plugins", "#{config.root}/vendor/plugins"] # # In the default implementation, as each plugin discovered in plugin_paths is initialized: # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory) @@ -394,7 +398,7 @@ module Rails initializer :load_application_initializers do if config.gems_dependencies_loaded - Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer| + Dir["#{configuration.root}/config/initializers/**/*.rb"].sort.each do |initializer| load(initializer) end end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index b5ac0e3ddc..322590f108 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -5,7 +5,7 @@ module Rails class Configuration attr_accessor :cache_classes, :load_paths, :load_once_paths, :gems_dependencies_loaded, :after_initialize_blocks, - :frameworks, :framework_root_path, :root_path, :plugin_paths, :plugins, + :frameworks, :framework_root_path, :root, :plugin_paths, :plugins, :plugin_loader, :plugin_locators, :gems, :loaded_plugins, :reload_plugins, :i18n, :gems, :whiny_nils, :consider_all_requests_local, :action_controller, :active_record, :action_view, :active_support, @@ -16,8 +16,6 @@ module Rails :eager_load_paths, :dependency_loading, :paths, :serve_static_assets def initialize - set_root_path! - @load_once_paths = [] @after_initialize_blocks = [] @loaded_plugins = [] @@ -34,38 +32,60 @@ module Rails @after_initialize_blocks << blk if blk end - def set_root_path! - raise 'RAILS_ROOT is not set' unless defined?(RAILS_ROOT) - raise 'RAILS_ROOT is not a directory' unless File.directory?(RAILS_ROOT) - - self.root_path = - # Pathname is incompatible with Windows, but Windows doesn't have - # real symlinks so File.expand_path is safe. - if RUBY_PLATFORM =~ /(:?mswin|mingw)/ - File.expand_path(RAILS_ROOT) - - # Otherwise use Pathname#realpath which respects symlinks. + def root + @root ||= begin + if defined?(RAILS_ROOT) + root = RAILS_ROOT else - Pathname.new(RAILS_ROOT).realpath.to_s + call_stack = caller.map { |p| p.split(':').first } + root_path = call_stack.detect { |p| p !~ %r[railties/lib/rails] } + root_path = File.dirname(root_path) + + while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/config.ru") + parent = File.dirname(root_path) + root_path = parent != root_path && parent + end + + Object.class_eval("RAILS_ROOT = ''") + + root = File.exist?("#{root_path}/config.ru") ? root_path : Dir.pwd end - @paths = Rails::Application::Root.new(root_path) - @paths.app "app", :load_path => true - @paths.app.metals "app/metal", :eager_load => true - @paths.app.models "app/models", :eager_load => true - @paths.app.controllers "app/controllers", builtin_directories, :eager_load => true - @paths.app.helpers "app/helpers", :eager_load => true - @paths.app.services "app/services", :load_path => true - @paths.lib "lib", :load_path => true - @paths.vendor "vendor", :load_path => true - @paths.vendor.plugins "vendor/plugins" - @paths.tmp "tmp" - @paths.tmp.cache "tmp/cache" - @paths.config "config" - @paths.config.locales "config/locales" - @paths.config.environments "config/environments", :glob => "#{RAILS_ENV}.rb" + root = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? + Pathname.new(root).expand_path.to_s : + Pathname.new(root).realpath.to_s - RAILS_ROOT.replace root_path + # TODO: Remove RAILS_ROOT + RAILS_ROOT.replace(root) + root + end + end + + def root=(root) + Object.class_eval("RAILS_ROOT = ''") unless defined?(RAILS_ROOT) + RAILS_ROOT.replace(root) + @root = root + end + + def paths + @paths ||= begin + paths = Rails::Application::Root.new(root) + paths.app "app", :load_path => true + paths.app.metals "app/metal", :eager_load => true + paths.app.models "app/models", :eager_load => true + paths.app.controllers "app/controllers", builtin_directories, :eager_load => true + paths.app.helpers "app/helpers", :eager_load => true + paths.app.services "app/services", :load_path => true + paths.lib "lib", :load_path => true + paths.vendor "vendor", :load_path => true + paths.vendor.plugins "vendor/plugins" + paths.tmp "tmp" + paths.tmp.cache "tmp/cache" + paths.config "config" + paths.config.locales "config/locales" + paths.config.environments "config/environments", :glob => "#{RAILS_ENV}.rb" + paths + end end # Enable threaded mode. Allows concurrent requests to controller actions and @@ -92,7 +112,7 @@ module Rails end def framework_root_path - defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails" + defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root}/vendor/rails" end def middleware @@ -109,12 +129,12 @@ module Rails end def routes_configuration_file - @routes_configuration_file ||= File.join(root_path, 'config', 'routes.rb') + @routes_configuration_file ||= File.join(root, 'config', 'routes.rb') end def controller_paths @controller_paths ||= begin - paths = [File.join(root_path, 'app', 'controllers')] + paths = [File.join(root, 'app', 'controllers')] paths.concat builtin_directories paths end @@ -122,8 +142,8 @@ module Rails def cache_store @cache_store ||= begin - if File.exist?("#{root_path}/tmp/cache/") - [ :file_store, "#{root_path}/tmp/cache/" ] + if File.exist?("#{root}/tmp/cache/") + [ :file_store, "#{root}/tmp/cache/" ] else :memory_store end @@ -131,11 +151,11 @@ module Rails end def database_configuration_file - @database_configuration_file ||= File.join(root_path, 'config', 'database.yml') + @database_configuration_file ||= File.join(root, 'config', 'database.yml') end def view_path - @view_path ||= File.join(root_path, 'app', 'views') + @view_path ||= File.join(root, 'app', 'views') end def eager_load_paths @@ -144,7 +164,7 @@ module Rails app/models app/controllers app/helpers - ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + ).map { |dir| "#{root}/#{dir}" }.select { |dir| File.directory?(dir) } end def load_paths @@ -152,10 +172,10 @@ module Rails paths = [] # Add the old mock paths only if the directories exists - paths.concat(Dir["#{root_path}/test/mocks/#{RAILS_ENV}"]) if File.exists?("#{root_path}/test/mocks/#{RAILS_ENV}") + paths.concat(Dir["#{root}/test/mocks/#{RAILS_ENV}"]) if File.exists?("#{root}/test/mocks/#{RAILS_ENV}") # Add the app's controller directory - paths.concat(Dir["#{root_path}/app/controllers/"]) + paths.concat(Dir["#{root}/app/controllers/"]) # Followed by the standard includes. paths.concat %w( @@ -167,7 +187,7 @@ module Rails app/services lib vendor - ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + ).map { |dir| "#{root}/#{dir}" }.select { |dir| File.directory?(dir) } paths.concat builtin_directories end @@ -179,7 +199,7 @@ module Rails end def log_path - @log_path ||= File.join(root_path, 'log', "#{RAILS_ENV}.log") + @log_path ||= File.join(root, 'log', "#{RAILS_ENV}.log") end def log_level @@ -191,7 +211,7 @@ module Rails end def plugin_paths - @plugin_paths ||= ["#{root_path}/vendor/plugins"] + @plugin_paths ||= ["#{root}/vendor/plugins"] end def plugin_loader @@ -213,8 +233,8 @@ module Rails i18n = Rails::OrderedOptions.new i18n.load_path = [] - if File.exist?(File.join(RAILS_ROOT, 'config', 'locales')) - i18n.load_path << Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')] + if File.exist?(File.join(root, 'config', 'locales')) + i18n.load_path << Dir[File.join(root, 'config', 'locales', '*.{rb,yml}')] i18n.load_path.flatten! end @@ -242,7 +262,7 @@ module Rails end def environment_path - "#{root_path}/config/environments/#{RAILS_ENV}.rb" + "#{root}/config/environments/#{RAILS_ENV}.rb" end def reload_plugins? diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb index 308d067701..0f24106353 100644 --- a/railties/lib/rails/paths.rb +++ b/railties/lib/rails/paths.rb @@ -26,7 +26,6 @@ module Rails @children = {} - # TODO: Move logic from set_root_path initializer @path = path @root = self @all_paths = [] diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 1bf59c2b8e..d90582d3db 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -7,11 +7,43 @@ module ApplicationTests def setup build_app boot_rails + Object.send(:remove_const, :RAILS_ROOT) end test "the application root is set correctly" do - # require "#{app_path}/config/environment" - # assert_equal app_path, Rails.application.root + require "#{app_path}/config/environment" + assert_equal app_path, Rails.application.root + end + + test "the application root can be set" do + FileUtils.mkdir_p("#{app_path}/hello") + add_to_config <<-RUBY + config.frameworks = [] + config.root = '#{app_path}/hello' + RUBY + require "#{app_path}/config/environment" + assert_equal "#{app_path}/hello", Rails.application.root + end + + test "the application root is detected as where config.ru is located" do + add_to_config <<-RUBY + config.frameworks = [] + RUBY + FileUtils.mv "#{app_path}/config.ru", "#{app_path}/config/config.ru" + require "#{app_path}/config/environment" + assert_equal "#{app_path}/config", Rails.application.root + end + + test "the application root is Dir.pwd if there is no config.ru" do + File.delete("#{app_path}/config.ru") + add_to_config <<-RUBY + config.frameworks = [] + RUBY + + Dir.chdir("#{app_path}/app") do + require "#{app_path}/config/environment" + assert_equal "#{app_path}/app", Rails.application.root + end end end end \ No newline at end of file diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index f83e0151a4..245577e8c0 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -25,8 +25,10 @@ module TestHelpers module Paths module_function + TMP_PATH = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp])) + def tmp_path(*args) - File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp] + args)) + File.join(TMP_PATH, *args) end def app_path(*args) @@ -88,10 +90,14 @@ module TestHelpers end end + add_to_config 'config.action_controller.session = { :key => "_myapp_session", :secret => "bac838a849c1d5c4de2e6a50af826079" }' + end + + def add_to_config(str) environment = File.read("#{app_path}/config/environment.rb") if environment =~ /(\n\s*end\s*)\Z/ File.open("#{app_path}/config/environment.rb", 'w') do |f| - f.puts $` + %'\nconfig.action_controller.session = { :key => "_myapp_session", :secret => "bac838a849c1d5c4de2e6a50af826079" }\n' + $1 + f.puts $` + "\n#{str}\n" + $1 end end end