aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-01-21 23:14:20 +0100
committerJosé Valim <jose.valim@gmail.com>2010-01-21 23:14:20 +0100
commit7fcf8590e788cef8b64cc266f75931c418902ca9 (patch)
treee6fbdc1f98ad236ff99c5525ae67521330600f24 /railties
parent2df1810cf3cde71fb15594eac022cab27d6497a1 (diff)
downloadrails-7fcf8590e788cef8b64cc266f75931c418902ca9.tar.gz
rails-7fcf8590e788cef8b64cc266f75931c418902ca9.tar.bz2
rails-7fcf8590e788cef8b64cc266f75931c418902ca9.zip
Massive cleanup in Railties and load stack.
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails.rb3
-rw-r--r--railties/lib/rails/application.rb64
-rw-r--r--railties/lib/rails/bootstrap.rb62
-rw-r--r--railties/lib/rails/configuration.rb233
-rw-r--r--railties/lib/rails/engine.rb107
-rw-r--r--railties/lib/rails/plugin.rb1
-rw-r--r--railties/lib/rails/railtie.rb68
7 files changed, 322 insertions, 216 deletions
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index 0bc7160815..93cf77ffd3 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -5,9 +5,10 @@ require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/logger'
require 'rails/initializable'
-require 'rails/application'
require 'rails/railtie'
require 'rails/plugin'
+require 'rails/engine'
+require 'rails/application'
require 'rails/railties_path'
require 'rails/version'
require 'rails/rack'
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 5c9892c630..898dd0ad9b 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,14 +1,12 @@
require "fileutils"
-require 'active_support/core_ext/module/delegation'
module Rails
- class Application
+ class Application < Engine
include Initializable
class << self
- attr_writer :config
- alias configure class_eval
- delegate :initialize!, :load_tasks, :load_generators, :root, :to => :instance
+ alias :configure :class_eval
+ delegate :initialize!, :load_tasks, :load_generators, :to => :instance
private :new
def instance
@@ -16,7 +14,16 @@ module Rails
end
def config
- @config ||= Configuration.new(Plugin::Configuration.default)
+ @config ||= Configuration.new(root)
+ end
+
+ def root
+ @root ||= find_root_with_file_flag("config.ru", Dir.pwd)
+ end
+
+ def inherited(base)
+ super
+ Railtie.plugins.delete(base)
end
def routes
@@ -24,8 +31,7 @@ module Rails
end
end
- delegate :config, :routes, :to => :'self.class'
- delegate :root, :middleware, :to => :config
+ delegate :routes, :to => :'self.class'
attr_reader :route_configuration_files
def initialize
@@ -38,12 +44,7 @@ module Rails
run_initializers(self)
self
end
-
- def require_environment
- require config.environment_path
- rescue LoadError
- end
-
+
def routes_changed_at
routes_changed_at = nil
@@ -59,6 +60,7 @@ module Rails
end
def reload_routes!
+ routes = Rails::Application.routes
routes.disable_clear_and_finalize = true
routes.clear!
@@ -70,6 +72,12 @@ module Rails
routes.disable_clear_and_finalize = false
end
+
+ def require_environment
+ require config.environment_path
+ rescue LoadError
+ end
+
def load_tasks
require "rails/tasks"
plugins.each { |p| p.load_tasks }
@@ -114,37 +122,23 @@ module Rails
app.call(env)
end
- initializer :load_application_initializers do
- Dir["#{root}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
- end
+ initializer :build_middleware_stack, :after => :load_application_initializers do
+ app
end
- initializer :build_middleware_stack do
- app
+ initializer :add_builtin_route do |app|
+ if Rails.env.development?
+ app.route_configuration_files << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
+ end
end
# Fires the user-supplied after_initialize block (Configuration#after_initialize)
- initializer :after_initialize do
+ initializer :after_initialize, :after => :build_middleware_stack do
config.after_initialize_blocks.each do |block|
block.call
end
end
- # Eager load application classes
- initializer :load_application_classes do
- next if $rails_rake_task
-
- if config.cache_classes
- config.eager_load_paths.each do |load_path|
- matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
- require_dependency file.sub(matcher, '\1')
- end
- end
- end
- end
-
# Disable dependency loading during request cycle
initializer :disable_dependency_loading do
if config.cache_classes && !config.dependency_loading
diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb
index 5db663f9ef..688ab2f4b0 100644
--- a/railties/lib/rails/bootstrap.rb
+++ b/railties/lib/rails/bootstrap.rb
@@ -12,30 +12,25 @@ module Rails
require "active_support/all" unless config.active_support.bare
end
- # Set the <tt>$LOAD_PATH</tt> based on the value of
- # Configuration#load_paths. Duplicates are removed.
- initializer :set_load_path do
- config.paths.add_to_load_path
- $LOAD_PATH.uniq!
- end
-
- # Set the paths from which Rails will automatically load source files, and
- # the load_once paths.
- initializer :set_autoload_paths do
- require 'active_support/dependencies'
- ActiveSupport::Dependencies.load_paths = expand_load_path(config.load_paths)
- ActiveSupport::Dependencies.load_once_paths = expand_load_path(config.load_once_paths)
-
- extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
- unless extra.empty?
- abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
- end_error
+ initializer :initialize_logger do
+ Rails.logger ||= config.logger || begin
+ logger = ActiveSupport::BufferedLogger.new(config.paths.log.to_a.first)
+ logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
+ logger.auto_flushing = false if Rails.env.production?
+ logger
+ rescue StandardError => e
+ logger = ActiveSupport::BufferedLogger.new(STDERR)
+ logger.level = ActiveSupport::BufferedLogger::WARN
+ logger.warn(
+ "Rails Error: Unable to access log file. Please ensure that #{config.log_path} exists and is chmod 0666. " +
+ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
+ )
+ logger
end
+ end
- # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
- config.load_once_paths.freeze
+ initializer :container do
+ # FIXME This is just a dumb initializer used as hook
end
# Create tmp directories
@@ -63,29 +58,6 @@ module Rails
end
end
- initializer :initialize_logger do
- Rails.logger ||= config.logger || begin
- logger = ActiveSupport::BufferedLogger.new(config.log_path)
- logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
- logger.auto_flushing = false if Rails.env.production?
- logger
- rescue StandardError => e
- logger = ActiveSupport::BufferedLogger.new(STDERR)
- logger.level = ActiveSupport::BufferedLogger::WARN
- logger.warn(
- "Rails Error: Unable to access log file. Please ensure that #{config.log_path} exists and is chmod 0666. " +
- "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
- )
- logger
- end
- end
-
- # Sets the logger for dependencies and cache store.
- initializer :initialize_framework_logging do
- ActiveSupport::Dependencies.logger ||= Rails.logger
- Rails.cache.logger ||= Rails.logger
- end
-
# Sets the dependency loading mechanism based on the value of
# Configuration#cache_classes.
initializer :initialize_dependency_mechanism do
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 7f1783a6b9..77248f2611 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -1,15 +1,9 @@
require 'active_support/ordered_options'
module Rails
- # Temporarily separate the plugin configuration class from the main
- # configuration class while this bit is being cleaned up.
- class Railtie::Configuration
- def self.default
- @default ||= new
- end
-
- def self.default_middleware_stack
- ActionDispatch::MiddlewareStack.new.tap do |middleware|
+ module SharedConfiguration
+ def self.middleware_stack
+ @default_middleware_stack ||= ActionDispatch::MiddlewareStack.new.tap do |middleware|
middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { Rails.application.config.serve_static_assets })
middleware.use('::Rack::Lock', :if => lambda { !ActionController::Base.allow_concurrency })
middleware.use('::Rack::Runtime')
@@ -26,16 +20,23 @@ module Rails
end
end
+ def self.options
+ @options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }
+ end
+ end
+
+ # Temporarily separate the plugin configuration class from the main
+ # configuration class while this bit is being cleaned up.
+ class Railtie::Configuration
+ def self.default
+ @default ||= new
+ end
+
attr_reader :middleware
- def initialize(base = nil)
- if base
- @options = base.options.dup
- @middleware = base.middleware.dup
- else
- @options = Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }
- @middleware = self.class.default_middleware_stack
- end
+ def initialize
+ @options = SharedConfiguration.options
+ @middleware = SharedConfiguration.middleware_stack
end
def respond_to?(name)
@@ -61,27 +62,65 @@ module Rails
/^(#{bits})(?:=)?$/
end
+ # TODO Remove :active_support as special case by adding a railtie
+ # for it and for I18n
def config_keys
- ([ :active_support, :action_view ] +
- Railtie.plugin_names).map { |n| n.to_s }.uniq
+ ([:active_support] + Railtie.plugin_names).map { |n| n.to_s }.uniq
end
end
- class Configuration < Railtie::Configuration
+ class Engine::Configuration < Railtie::Configuration
+ attr_reader :root
+
+ def initialize(root)
+ @root = root
+ super()
+ end
+
+ def paths
+ @paths ||= begin
+ paths = Rails::Application::Root.new(root)
+ paths.app "app", :load_path => true
+ paths.app_glob "app/*", :load_path => true, :eager_load => true
+ paths.app.controllers "app/controllers"
+ paths.app.metals "app/metal"
+ paths.app.views "app/views"
+ paths.lib "lib", :load_path => true
+ paths.config "config"
+ paths.config.environments "config/environments", :glob => "#{Rails.env}.rb"
+ paths.config.initializers "config/initializers"
+ paths.config.locales "config/locales"
+ paths.config.routes "config/routes.rb"
+ paths
+ end
+ end
+
+ def eager_load_paths
+ @eager_load_paths ||= paths.eager_load
+ end
+
+ def load_once_paths
+ @eager_load_paths ||= paths.load_once
+ end
+
+ def load_paths
+ @load_paths ||= paths.load_paths
+ end
+ end
+
+ class Configuration < Engine::Configuration
attr_accessor :after_initialize_blocks, :cache_classes, :colorize_logging,
:consider_all_requests_local, :dependency_loading, :filter_parameters,
- :load_once_paths, :logger, :metals, :plugins,
+ :logger, :metals, :plugins,
:preload_frameworks, :reload_plugins, :serve_static_assets,
:time_zone, :whiny_nils
attr_writer :cache_store, :controller_paths,
- :database_configuration_file, :eager_load_paths,
- :i18n, :load_paths, :log_level, :log_path, :paths,
- :routes_configuration_file, :view_path
+ :database_configuration_file,
+ :i18n, :log_level, :log_path
- def initialize(base = nil)
+ def initialize(*)
super
- @load_once_paths = []
@after_initialize_blocks = []
@filter_parameters = []
@dependency_loading = true
@@ -92,46 +131,23 @@ module Rails
@after_initialize_blocks << blk if blk
end
- def root
- @root ||= begin
- call_stack = caller.map { |p| p.split(':').first }
- root_path = call_stack.detect { |p| p !~ %r[railties/lib/rails|rack/lib/rack] }
- 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
-
- root = File.exist?("#{root_path}/config.ru") ? root_path : Dir.pwd
-
- RUBY_PLATFORM =~ /(:?mswin|mingw)/ ?
- Pathname.new(root).expand_path :
- Pathname.new(root).realpath
- end
- end
-
- def root=(root)
- @root = Pathname.new(root).expand_path
- 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 = super
+ paths.builtin_controller builtin_directories, :eager_load => true
+ paths.config.database "config/database.yml"
+ paths.log "log/#{Rails.env}.log"
+ paths.tmp "tmp"
+ paths.tmp.cache "tmp/cache"
+ paths.vendor "vendor", :load_path => true
+ paths.vendor.plugins "vendor/plugins"
+
+ if File.exists?("#{root}/test/mocks/#{Rails.env}")
+ ActiveSupport::Deprecation.warn "\"RAILS_ROOT/test/mocks/#{Rails.env}\" won't be added " <<
+ "automatically to load paths anymore in next releases."
+ paths.mocks_path "test/mocks/#{Rails.env}", :load_path => true
+ end
+
paths
end
end
@@ -163,17 +179,61 @@ module Rails
# YAML::load.
def database_configuration
require 'erb'
- YAML::load(ERB.new(IO.read(database_configuration_file)).result)
+ YAML::load(ERB.new(IO.read(paths.config.database.to_a.first)).result)
+ end
+
+ def view_path=(value)
+ ActiveSupport::Deprecation.warn "config.view_path= is deprecated, " <<
+ "please do config.paths.app.views= instead", caller
+ paths.app.views = value
+ end
+
+ def view_path
+ ActiveSupport::Deprecation.warn "config.view_path is deprecated, " <<
+ "please do config.paths.app.views instead", caller
+ paths.app.views.to_a.first
+ end
+
+ def routes_configuration_file=(value)
+ ActiveSupport::Deprecation.warn "config.routes_configuration_file= is deprecated, " <<
+ "please do config.paths.config.routes= instead", caller
+ paths.config.routes = value
end
def routes_configuration_file
- @routes_configuration_file ||= File.join(root, 'config', 'routes.rb')
+ ActiveSupport::Deprecation.warn "config.routes_configuration_file is deprecated, " <<
+ "please do config.paths.config.routes instead", caller
+ paths.config.routes.to_a.first
+ end
+
+ def database_configuration_file=(value)
+ ActiveSupport::Deprecation.warn "config.database_configuration_file= is deprecated, " <<
+ "please do config.paths.config.database= instead", caller
+ paths.config.database = value
+ end
+
+ def database_configuration_file
+ ActiveSupport::Deprecation.warn "config.database_configuration_file is deprecated, " <<
+ "please do config.paths.config.database instead", caller
+ paths.config.database.to_a.first
+ end
+
+ def log_path=(value)
+ ActiveSupport::Deprecation.warn "config.log_path= is deprecated, " <<
+ "please do config.paths.log= instead", caller
+ paths.config.log = value
end
- def builtin_routes_configuration_file
- @builtin_routes_configuration_file ||= File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
+ def log_path
+ ActiveSupport::Deprecation.warn "config.log_path is deprecated, " <<
+ "please do config.paths.log instead", caller
+ paths.config.log.to_a.first
end
+
+
+ # TODO Router needs this, but this wouldn't work with engines.
+ # There is a high chance of plugins routes to be broken.
def controller_paths
@controller_paths ||= begin
paths = [File.join(root, 'app', 'controllers')]
@@ -192,46 +252,11 @@ module Rails
end
end
- def database_configuration_file
- @database_configuration_file ||= File.join(root, 'config', 'database.yml')
- end
-
- def view_path
- @view_path ||= File.join(root, 'app', 'views')
- end
-
- def eager_load_paths
- @eager_load_paths ||= ["#{root}/app/*"]
- end
-
- def load_paths
- @load_paths ||= begin
- paths = []
-
- # Add the old mock paths only if the directories exists
- paths.concat(Dir["#{root}/test/mocks/#{Rails.env}"]) if File.exists?("#{root}/test/mocks/#{Rails.env}")
-
- # Followed by the standard includes.
- paths.concat %w(
- app
- app/*
- lib
- vendor
- ).map { |dir| "#{root}/#{dir}" }
-
- paths.concat builtin_directories
- end
- end
-
+ # Include builtins only in the development environment.
def builtin_directories
- # Include builtins only in the development environment.
Rails.env.development? ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
end
- def log_path
- @log_path ||= File.join(root, 'log', "#{Rails.env}.log")
- end
-
def log_level
@log_level ||= Rails.env.production? ? :info : :debug
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
new file mode 100644
index 0000000000..21c78036bd
--- /dev/null
+++ b/railties/lib/rails/engine.rb
@@ -0,0 +1,107 @@
+require 'active_support/core_ext/module/delegation'
+
+module Rails
+ # TODO Move I18n and views path setup
+ class Engine < Railtie
+
+ class << self
+ attr_accessor :called_from
+
+ def root
+ @root ||= find_root_with_file_flag("lib")
+ end
+
+ def config
+ @config ||= Configuration.new(root)
+ end
+
+ def inherited(base)
+ base.called_from = begin
+ call_stack = caller.map { |p| p.split(':').first }
+ File.dirname(call_stack.detect { |p| p !~ %r[railties/lib/rails|rack/lib/rack] })
+ end
+ super
+ end
+
+ protected
+
+ def find_root_with_file_flag(flag, default=nil)
+ root_path = self.called_from
+
+ while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
+ parent = File.dirname(root_path)
+ root_path = parent != root_path && parent
+ end
+
+ root = File.exist?("#{root_path}/flag") ? root_path : default
+
+ raise "Could not find root path for #{self}" unless root
+
+ RUBY_PLATFORM =~ /(:?mswin|mingw)/ ?
+ Pathname.new(root).expand_path :
+ Pathname.new(root).realpath
+ end
+ end
+
+ delegate :root, :config, :to => :'self.class'
+ delegate :middleware, :to => :config
+
+ # Add configured load paths to ruby load paths and remove duplicates.
+ initializer :set_load_path, :before => :container do
+ config.paths.add_to_load_path
+ $LOAD_PATH.uniq!
+ end
+
+ # Set the paths from which Rails will automatically load source files,
+ # and the load_once paths.
+ initializer :set_autoload_paths, :before => :container do
+ require 'active_support/dependencies'
+
+ ActiveSupport::Dependencies.load_paths = expand_load_path(config.load_paths)
+ ActiveSupport::Dependencies.load_once_paths = expand_load_path(config.load_once_paths)
+
+ extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
+
+ unless extra.empty?
+ abort <<-end_error
+ load_once_paths must be a subset of the load_paths.
+ Extra items in load_once_paths: #{extra * ','}
+ end_error
+ end
+
+ # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
+ config.load_once_paths.freeze
+ end
+
+ initializer :load_application_initializers do
+ Dir["#{root}/config/initializers/**/*.rb"].sort.each do |initializer|
+ load(initializer)
+ end
+ end
+
+ # Routing must be initialized after plugins to allow the former to extend the routes
+ initializer :initialize_routing do |app|
+ app.route_configuration_files.concat(config.paths.config.routes.to_a)
+ end
+
+ # Eager load application classes
+ initializer :load_application_classes do |app|
+ next if $rails_rake_task
+
+ if app.config.cache_classes
+ config.eager_load_paths.each do |load_path|
+ matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
+ require_dependency file.sub(matcher, '\1')
+ end
+ end
+ end
+ end
+
+ private
+
+ def expand_load_path(load_paths)
+ load_paths.map { |path| Dir.glob(path.to_s) }.flatten.uniq
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index c3b81bcd3e..dde06bfcbd 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -57,7 +57,6 @@ module Rails
end
end
- # TODO Isn't it supposed to be :after => "action_controller.initialize_routing" ?
initializer :add_routing_file, :after => :initialize_routing do |app|
routing_file = "#{path}/config/routes.rb"
if File.exist?(routing_file)
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index e3297148e5..a7f52b25e4 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -2,43 +2,51 @@ module Rails
class Railtie
include Initializable
- def self.plugin_name(plugin_name = nil)
- @plugin_name ||= name.demodulize.underscore
- @plugin_name = plugin_name if plugin_name
- @plugin_name
- end
+ ABSTRACT_RAILTIES = %w(Rails::Plugin Rails::Engine Rails::Application)
- def self.inherited(klass)
- @plugins ||= []
- @plugins << klass unless klass == Plugin
- end
+ class << self
+ def abstract_railtie?(base)
+ ABSTRACT_RAILTIES.include?(base.name)
+ end
- def self.plugins
- @plugins
- end
+ def inherited(base)
+ @@plugins ||= []
+ @@plugins << base unless abstract_railtie?(base)
+ end
- def self.plugin_names
- plugins.map { |p| p.plugin_name }
- end
+ def plugin_name(plugin_name = nil)
+ @plugin_name ||= name.demodulize.underscore
+ @plugin_name = plugin_name if plugin_name
+ @plugin_name
+ end
- def self.config
- Configuration.default
- end
+ def plugins
+ @@plugins
+ end
- def self.subscriber(subscriber)
- Rails::Subscriber.add(plugin_name, subscriber)
- end
+ def plugin_names
+ plugins.map { |p| p.plugin_name }
+ end
- def self.rake_tasks(&blk)
- @rake_tasks ||= []
- @rake_tasks << blk if blk
- @rake_tasks
- end
+ def config
+ Configuration.default
+ end
+
+ def subscriber(subscriber)
+ Rails::Subscriber.add(plugin_name, subscriber)
+ end
+
+ def rake_tasks(&blk)
+ @rake_tasks ||= []
+ @rake_tasks << blk if blk
+ @rake_tasks
+ end
- def self.generators(&blk)
- @generators ||= []
- @generators << blk if blk
- @generators
+ def generators(&blk)
+ @generators ||= []
+ @generators << blk if blk
+ @generators
+ end
end
def rake_tasks