aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails')
-rw-r--r--railties/lib/rails/all.rb1
-rw-r--r--railties/lib/rails/application.rb178
-rw-r--r--railties/lib/rails/application/bootstrap.rb81
-rw-r--r--railties/lib/rails/application/configuration.rb85
-rw-r--r--railties/lib/rails/application/finisher.rb43
-rw-r--r--railties/lib/rails/application/railties.rb31
-rw-r--r--railties/lib/rails/application/routes_reloader.rb49
-rw-r--r--railties/lib/rails/bootstrap.rb161
-rw-r--r--railties/lib/rails/commands/console.rb8
-rw-r--r--railties/lib/rails/configuration.rb395
-rw-r--r--railties/lib/rails/console/app.rb (renamed from railties/lib/rails/console_app.rb)11
-rw-r--r--railties/lib/rails/console/helpers.rb (renamed from railties/lib/rails/console_with_helpers.rb)0
-rw-r--r--railties/lib/rails/console/sandbox.rb (renamed from railties/lib/rails/console_sandbox.rb)0
-rw-r--r--railties/lib/rails/engine.rb128
-rw-r--r--railties/lib/rails/engine/configurable.rb25
-rw-r--r--railties/lib/rails/engine/configuration.rb49
-rw-r--r--railties/lib/rails/initializable.rb19
-rw-r--r--railties/lib/rails/paths.rb44
-rw-r--r--railties/lib/rails/plugin.rb63
-rw-r--r--railties/lib/rails/rack/metal.rb29
-rw-r--r--railties/lib/rails/railtie.rb84
-rw-r--r--railties/lib/rails/railtie/configurable.rb23
-rw-r--r--railties/lib/rails/railtie/configuration.rb9
-rw-r--r--railties/lib/rails/tasks/documentation.rake54
-rw-r--r--railties/lib/rails/tasks/middleware.rake2
-rw-r--r--railties/lib/rails/tasks/routes.rake1
26 files changed, 890 insertions, 683 deletions
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index 7dfe2b8b63..b8292a9b7e 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -1,6 +1,7 @@
require "rails"
%w(
+ active_support
active_model
active_record
action_controller
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 8366127476..ab66d1e90b 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,118 +1,87 @@
-require "fileutils"
-require 'active_support/core_ext/module/delegation'
+require 'fileutils'
+require 'rails/railties_path'
+require 'rails/plugin'
+require 'rails/engine'
module Rails
- class Application
- include Initializable
+ class Application < Engine
+ autoload :Bootstrap, 'rails/application/bootstrap'
+ autoload :Configuration, 'rails/application/configuration'
+ autoload :Finisher, 'rails/application/finisher'
+ autoload :Railties, 'rails/application/railties'
+ autoload :RoutesReloader, 'rails/application/routes_reloader'
class << self
- attr_writer :config
- alias configure class_eval
- delegate :call,
- :initialize!,
- :load_generators,
- :load_tasks,
- :middleware,
- :root,
- :to => :instance
-
private :new
+ alias :configure :class_eval
+
def instance
- @instance ||= new
+ if instance_of?(Rails::Application)
+ Rails.application.instance
+ else
+ @instance ||= new
+ end
end
- def config
- @config ||= Configuration.new(Plugin::Configuration.default)
+ def inherited(base)
+ raise "You cannot have more than one Rails::Application" if Rails.application
+ super
+ Rails.application = base.instance
end
- def routes
- ActionController::Routing::Routes
+ protected
+
+ def method_missing(*args, &block)
+ instance.send(*args, &block)
end
end
- delegate :config, :routes, :to => :'self.class'
- delegate :root, :middleware, :to => :config
- attr_reader :route_configuration_files
-
- def initialize
- require_environment
- Rails.application ||= self
- @route_configuration_files = []
+ def require_environment!
+ environment = config.paths.config.environment.to_a.first
+ require environment if environment
end
- def initialize!
- run_initializers(self)
- self
+ def config
+ @config ||= Application::Configuration.new(self.class.find_root_with_flag("config.ru", Dir.pwd))
end
- def require_environment
- require config.environment_path
- rescue LoadError
+ def routes
+ ::ActionController::Routing::Routes
end
- def routes_changed_at
- routes_changed_at = nil
-
- route_configuration_files.each do |config|
- config_changed_at = File.stat(config).mtime
-
- if routes_changed_at.nil? || config_changed_at > routes_changed_at
- routes_changed_at = config_changed_at
- end
- end
+ def railties
+ @railties ||= Railties.new(config)
+ end
- routes_changed_at
+ def routes_reloader
+ @routes_reloader ||= RoutesReloader.new(config)
end
def reload_routes!
- routes.disable_clear_and_finalize = true
-
- routes.clear!
- route_configuration_files.each { |config| load(config) }
- routes.finalize!
+ routes_reloader.reload!
+ end
- nil
- ensure
- routes.disable_clear_and_finalize = false
+ def initialize!
+ run_initializers(self)
+ self
end
def load_tasks
- require "rails/tasks"
- plugins.each { |p| p.load_tasks }
- # Load all application tasks
- # TODO: extract out the path to the rake tasks
- Dir["#{root}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
- task :environment do
- $rails_rake_task = true
- initialize!
- end
+ initialize_tasks
+ super
+ railties.all { |r| r.load_tasks }
+ self
end
def load_generators
- plugins.each { |p| p.load_generators }
- end
-
- def initializers
- initializers = Bootstrap.new(self).initializers
- plugins.each { |p| initializers += p.initializers }
- initializers += super
- initializers
- end
-
- # TODO: Fix this method. It loads all railties independent if :all is given
- # or not, otherwise frameworks are never loaded.
- def plugins
- @plugins ||= begin
- plugin_names = (config.plugins || [:all]).map { |p| p.to_sym }
- Railtie.plugins.map(&:new) + Plugin.all(plugin_names, config.paths.vendor.plugins)
- end
+ initialize_generators
+ super
+ railties.all { |r| r.load_generators }
+ self
end
def app
- @app ||= begin
- reload_routes!
- middleware.build(routes)
- end
+ @app ||= middleware.build(routes)
end
def call(env)
@@ -120,42 +89,31 @@ module Rails
app.call(env)
end
- initializer :load_application_initializers do
- Dir["#{root}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
- end
+ def initializers
+ initializers = Bootstrap.initializers
+ initializers += super
+ railties.all { |r| initializers += r.initializers }
+ initializers += Finisher.initializers
+ initializers
end
- initializer :build_middleware_stack do
- app
- end
+ protected
- # Fires the user-supplied after_initialize block (Configuration#after_initialize)
- initializer :after_initialize do
- config.after_initialize_blocks.each do |block|
- block.call
+ def initialize_tasks
+ require "rails/tasks"
+ task :environment do
+ $rails_rake_task = true
+ initialize!
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
+ def initialize_generators
+ require "rails/generators"
end
- # Disable dependency loading during request cycle
- initializer :disable_dependency_loading do
- if config.cache_classes && !config.dependency_loading
- ActiveSupport::Dependencies.unhook!
- end
+ # Application is always reloadable when config.cache_classes is false.
+ def reloadable?(app)
+ true
end
end
end
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
new file mode 100644
index 0000000000..3c339ffc57
--- /dev/null
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -0,0 +1,81 @@
+module Rails
+ class Application
+ module Bootstrap
+ include Initializable
+
+ initializer :load_environment_config do |app|
+ app.require_environment!
+ end
+
+ initializer :load_all_active_support do |app|
+ require "active_support/all" unless app.config.active_support.bare
+ end
+
+ # Preload all frameworks specified by the Configuration#frameworks.
+ # Used by Passenger to ensure everything's loaded before forking and
+ # to avoid autoload race conditions in JRuby.
+ initializer :preload_frameworks do |app|
+ require 'active_support/dependencies'
+ ActiveSupport::Autoload.eager_autoload! if app.config.preload_frameworks
+ end
+
+ # Initialize the logger early in the stack in case we need to log some deprecation.
+ initializer :initialize_logger do |app|
+ Rails.logger ||= app.config.logger || begin
+ path = app.config.paths.log.to_a.first
+ logger = ActiveSupport::BufferedLogger.new(path)
+ logger.level = ActiveSupport::BufferedLogger.const_get(app.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 #{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
+
+ # Initialize cache early in the stack so railties can make use of it.
+ initializer :initialize_cache do |app|
+ unless defined?(RAILS_CACHE)
+ silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(app.config.cache_store) }
+
+ if RAILS_CACHE.respond_to?(:middleware)
+ app.config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
+ end
+ end
+ end
+
+ # Initialize rails subscriber on top of notifications.
+ initializer :initialize_subscriber do |app|
+ require 'active_support/notifications'
+
+ if app.config.colorize_logging == false
+ Rails::Subscriber.colorize_logging = false
+ app.config.generators.colorize_logging = false
+ end
+
+ ActiveSupport::Notifications.subscribe do |*args|
+ Rails::Subscriber.dispatch(args)
+ end
+ end
+
+ initializer :set_clear_dependencies_hook do |app|
+ unless app.config.cache_classes
+ ActionDispatch::Callbacks.after do
+ ActiveSupport::Dependencies.clear
+ end
+ end
+ end
+
+ # Sets the dependency loading mechanism.
+ # TODO: Remove files from the $" and always use require.
+ initializer :initialize_dependency_mechanism do |app|
+ ActiveSupport::Dependencies.mechanism = app.config.cache_classes ? :require : :load
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
new file mode 100644
index 0000000000..aaf18b5f51
--- /dev/null
+++ b/railties/lib/rails/application/configuration.rb
@@ -0,0 +1,85 @@
+require 'rails/engine/configuration'
+
+module Rails
+ class Application
+ class Configuration < ::Rails::Engine::Configuration
+ include ::Rails::Configuration::Deprecated
+
+ attr_accessor :cache_classes, :cache_store, :colorize_logging,
+ :consider_all_requests_local, :dependency_loading,
+ :filter_parameters, :log_level, :logger, :metals,
+ :plugins, :preload_frameworks, :reload_plugins,
+ :serve_static_assets, :time_zone, :whiny_nils
+
+ def initialize(*)
+ super
+ @filter_parameters = []
+ @dependency_loading = true
+ @serve_static_assets = true
+ end
+
+ def paths
+ @paths ||= begin
+ paths = super
+ paths.app.controllers << builtin_controller if builtin_controller
+ 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 future releases"
+ paths.mocks_path "test/mocks", :load_path => true, :glob => Rails.env
+ end
+
+ paths
+ end
+ end
+
+ # Enable threaded mode. Allows concurrent requests to controller actions and
+ # multiple database connections. Also disables automatic dependency loading
+ # after boot, and disables reloading code on every request, as these are
+ # fundamentally incompatible with thread safety.
+ def threadsafe!
+ self.preload_frameworks = true
+ self.cache_classes = true
+ self.dependency_loading = false
+ self.action_controller.allow_concurrency = true if respond_to?(:action_controller)
+ self
+ end
+
+ # Loads and returns the contents of the #database_configuration_file. The
+ # contents of the file are processed via ERB before being sent through
+ # YAML::load.
+ def database_configuration
+ require 'erb'
+ YAML::load(ERB.new(IO.read(paths.config.database.to_a.first)).result)
+ end
+
+ def cache_store
+ @cache_store ||= begin
+ if File.exist?("#{root}/tmp/cache/")
+ [ :file_store, "#{root}/tmp/cache/" ]
+ else
+ :memory_store
+ end
+ end
+ end
+
+ def builtin_controller
+ File.join(RAILTIES_PATH, "builtin", "rails_info") if Rails.env.development?
+ end
+
+ def log_level
+ @log_level ||= Rails.env.production? ? :info : :debug
+ end
+
+ def time_zone
+ @time_zone ||= "UTC"
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
new file mode 100644
index 0000000000..5cc5b4ae88
--- /dev/null
+++ b/railties/lib/rails/application/finisher.rb
@@ -0,0 +1,43 @@
+module Rails
+ class Application
+ module Finisher
+ include Initializable
+
+ initializer :ensure_load_once_paths_as_subset do
+ 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
+ end
+
+ initializer :add_builtin_route do |app|
+ if Rails.env.development?
+ Rails::Application::RoutesReloader.paths << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
+ end
+ end
+
+ initializer :build_middleware_stack do |app|
+ app.app
+ end
+
+ # Fires the user-supplied after_initialize block (config#after_initialize)
+ initializer :after_initialize do |app|
+ app.config.after_initialize_blocks.each do |block|
+ block.call(app)
+ end
+ end
+
+ # Disable dependency loading during request cycle
+ initializer :disable_dependency_loading do |app|
+ if app.config.cache_classes && !app.config.dependency_loading
+ ActiveSupport::Dependencies.unhook!
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/railties.rb b/railties/lib/rails/application/railties.rb
new file mode 100644
index 0000000000..b3e6693f89
--- /dev/null
+++ b/railties/lib/rails/application/railties.rb
@@ -0,0 +1,31 @@
+module Rails
+ class Application
+ class Railties
+ # TODO Write tests for this behavior extracted from Application
+ def initialize(config)
+ @config = config
+ end
+
+ def all(&block)
+ @all ||= railties + engines + plugins
+ @all.each(&block) if block
+ @all
+ end
+
+ def railties
+ @railties ||= ::Rails::Railtie.subclasses.map(&:new)
+ end
+
+ def engines
+ @engines ||= ::Rails::Engine.subclasses.map(&:new)
+ end
+
+ def plugins
+ @plugins ||= begin
+ plugin_names = (@config.plugins || [:all]).map { |p| p.to_sym }
+ Plugin.all(plugin_names, @config.paths.vendor.plugins)
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
new file mode 100644
index 0000000000..fe0cfb7801
--- /dev/null
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -0,0 +1,49 @@
+module Rails
+ class Application
+ # TODO Write tests for this behavior extracted from Application
+ class RoutesReloader
+ def self.paths
+ @paths ||= []
+ end
+
+ def initialize(config)
+ @config, @last_change_at = config, nil
+ end
+
+ def changed_at
+ routes_changed_at = nil
+
+ self.class.paths.each do |path|
+ config_changed_at = File.stat(path).mtime
+
+ if routes_changed_at.nil? || config_changed_at > routes_changed_at
+ routes_changed_at = config_changed_at
+ end
+ end
+
+ routes_changed_at
+ end
+
+ def reload!
+ routes = Rails::Application.routes
+ routes.disable_clear_and_finalize = true
+
+ routes.clear!
+ self.class.paths.each { |path| load(path) }
+ routes.finalize!
+
+ nil
+ ensure
+ routes.disable_clear_and_finalize = false
+ end
+
+ def reload_if_changed
+ current_change_at = changed_at
+ if @last_change_at != current_change_at
+ @last_change_at = current_change_at
+ reload!
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb
deleted file mode 100644
index 5db663f9ef..0000000000
--- a/railties/lib/rails/bootstrap.rb
+++ /dev/null
@@ -1,161 +0,0 @@
-module Rails
- class Bootstrap #< Railtie
- include Initializable
-
- def initialize(application)
- @application = application
- end
-
- delegate :config, :root, :to => :'@application'
-
- initializer :load_all_active_support do
- 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
- end
-
- # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
- config.load_once_paths.freeze
- end
-
- # Create tmp directories
- initializer :ensure_tmp_directories_exist do
- %w(cache pids sessions sockets).each do |dir_to_make|
- FileUtils.mkdir_p(File.join(root, 'tmp', dir_to_make))
- end
- end
-
- # Preload all frameworks specified by the Configuration#frameworks.
- # Used by Passenger to ensure everything's loaded before forking and
- # to avoid autoload race conditions in JRuby.
- initializer :preload_frameworks do
- ActiveSupport::Autoload.eager_autoload! if config.preload_frameworks
- end
-
- initializer :initialize_cache do
- unless defined?(RAILS_CACHE)
- silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) }
-
- if RAILS_CACHE.respond_to?(:middleware)
- # Insert middleware to setup and teardown local cache for each request
- config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
- end
- 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
- # TODO: Remove files from the $" and always use require
- ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
- end
-
- # Loads support for "whiny nil" (noisy warnings when methods are invoked
- # on +nil+ values) if Configuration#whiny_nils is true.
- initializer :initialize_whiny_nils do
- require 'active_support/whiny_nil' if config.whiny_nils
- end
-
- # Sets the default value for Time.zone
- # If assigned value cannot be matched to a TimeZone, an exception will be raised.
- initializer :initialize_time_zone do
- require 'active_support/core_ext/time/zones'
- zone_default = Time.__send__(:get_zone, config.time_zone)
-
- unless zone_default
- raise \
- 'Value assigned to config.time_zone not recognized.' +
- 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
- end
-
- Time.zone_default = zone_default
- end
-
- # Set the i18n configuration from config.i18n but special-case for the load_path which should be
- # appended to what's already set instead of overwritten.
- initializer :initialize_i18n do
- require 'active_support/i18n'
-
- config.i18n.each do |setting, value|
- if setting == :load_path
- I18n.load_path += value
- else
- I18n.send("#{setting}=", value)
- end
- end
-
- ActionDispatch::Callbacks.to_prepare do
- I18n.reload!
- end
- end
-
- initializer :set_clear_dependencies_hook do
- unless config.cache_classes
- ActionDispatch::Callbacks.after do
- ActiveSupport::Dependencies.clear
- end
- end
- end
-
- initializer :initialize_notifications do
- require 'active_support/notifications'
-
- if config.colorize_logging == false
- Rails::Subscriber.colorize_logging = false
- config.generators.colorize_logging = false
- end
-
- ActiveSupport::Notifications.subscribe do |*args|
- Rails::Subscriber.dispatch(args)
- end
- end
-
- private
- def expand_load_path(load_paths)
- load_paths.map { |path| Dir.glob(path.to_s) }.flatten.uniq
- end
- end
-end
diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb
index 27ac7fd20a..a984eff6e2 100644
--- a/railties/lib/rails/commands/console.rb
+++ b/railties/lib/rails/commands/console.rb
@@ -1,6 +1,6 @@
require 'optparse'
require 'irb'
-require "irb/completion"
+require 'irb/completion'
module Rails
class Console
@@ -24,9 +24,9 @@ module Rails
end
@app.initialize!
- require "rails/console_app"
- require "rails/console_sandbox" if options[:sandbox]
- require "rails/console_with_helpers"
+ require "rails/console/app"
+ require "rails/console/sandbox" if options[:sandbox]
+ require "rails/console/helpers"
if options[:debugger]
begin
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 21736a28eb..3c5c1c1e16 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -1,296 +1,84 @@
require 'active_support/ordered_options'
+require 'rails/paths'
+require 'rails/rack'
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|
- 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')
- middleware.use('::Rails::Rack::Logger')
- middleware.use('::ActionDispatch::ShowExceptions', lambda { ActionController::Base.consider_all_requests_local })
- middleware.use('::ActionDispatch::Callbacks', lambda { !Rails.application.config.cache_classes })
- middleware.use('::ActionDispatch::Cookies')
- middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
- middleware.use('::ActionDispatch::Flash', :if => lambda { ActionController::Base.session_store })
- middleware.use(lambda { Rails::Rack::Metal.new(Rails.application.config.paths.app.metals.to_a, Rails.application.config.metals) })
- middleware.use('ActionDispatch::ParamsParser')
- middleware.use('::Rack::MethodOverride')
- middleware.use('::ActionDispatch::Head')
- end
- 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
- end
-
- def respond_to?(name)
- super || name.to_s =~ config_key_regexp
- end
-
- protected
-
- attr_reader :options
-
- private
-
- def method_missing(name, *args, &blk)
- if name.to_s =~ config_key_regexp
- return $2 == '=' ? @options[$1] = args.first : @options[$1]
+ module Configuration
+ module Shared
+ def middleware
+ @@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')
+ middleware.use('::Rails::Rack::Logger')
+ middleware.use('::ActionDispatch::ShowExceptions', lambda { ActionController::Base.consider_all_requests_local })
+ middleware.use('::ActionDispatch::Callbacks', lambda { !Rails.application.config.cache_classes })
+ middleware.use('::ActionDispatch::Cookies')
+ middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
+ middleware.use('::ActionDispatch::Flash', :if => lambda { ActionController::Base.session_store })
+ middleware.use(lambda { Rails::Rack::Metal.new(Rails.application.config.metals) })
+ middleware.use('ActionDispatch::ParamsParser')
+ middleware.use('::Rack::MethodOverride')
+ middleware.use('::ActionDispatch::Head')
+ end
end
- super
- end
-
- def config_key_regexp
- bits = config_keys.map { |n| Regexp.escape(n.to_s) }.join('|')
- /^(#{bits})(?:=)?$/
- end
-
- def config_keys
- ([ :active_support, :action_view ] +
- Railtie.plugin_names).map { |n| n.to_s }.uniq
- end
- end
-
- class Configuration < Railtie::Configuration
- attr_accessor :after_initialize_blocks, :cache_classes, :colorize_logging,
- :consider_all_requests_local, :dependency_loading, :filter_parameters,
- :load_once_paths, :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
-
- def initialize(base = nil)
- super
- @load_once_paths = []
- @after_initialize_blocks = []
- @filter_parameters = []
- @dependency_loading = true
- @serve_static_assets = true
- end
-
- def after_initialize(&blk)
- @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
+ # Holds generators configuration:
+ #
+ # config.generators do |g|
+ # g.orm :datamapper, :migration => true
+ # g.template_engine :haml
+ # g.test_framework :rspec
+ # end
+ #
+ # If you want to disable color in console, do:
+ #
+ # config.generators.colorize_logging = false
+ #
+ def generators
+ @@generators ||= Rails::Configuration::Generators.new
+ if block_given?
+ yield @@generators
+ else
+ @@generators
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
+ def after_initialize_blocks
+ @@after_initialize_blocks ||= []
end
- end
-
- def frameworks(*args)
- raise "config.frameworks is no longer supported. See the generated " \
- "config/boot.rb for steps on how to limit the frameworks that " \
- "will be loaded"
- end
- alias frameworks= frameworks
- # Enable threaded mode. Allows concurrent requests to controller actions and
- # multiple database connections. Also disables automatic dependency loading
- # after boot, and disables reloading code on every request, as these are
- # fundamentally incompatible with thread safety.
- def threadsafe!
- self.preload_frameworks = true
- self.cache_classes = true
- self.dependency_loading = false
-
- if respond_to?(:action_controller)
- action_controller.allow_concurrency = true
+ def after_initialize(&blk)
+ after_initialize_blocks << blk if blk
end
- self
- end
-
- # Loads and returns the contents of the #database_configuration_file. The
- # contents of the file are processed via ERB before being sent through
- # YAML::load.
- def database_configuration
- require 'erb'
- YAML::load(ERB.new(IO.read(database_configuration_file)).result)
- end
-
- def routes_configuration_file
- @routes_configuration_file ||= File.join(root, 'config', 'routes.rb')
- end
- def builtin_routes_configuration_file
- @builtin_routes_configuration_file ||= File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
- end
-
- def controller_paths
- @controller_paths ||= begin
- paths = [File.join(root, 'app', 'controllers')]
- paths.concat builtin_directories
- paths
+ def respond_to?(name)
+ super || name.to_s =~ config_key_regexp
end
- end
- def cache_store
- @cache_store ||= begin
- if File.exist?("#{root}/tmp/cache/")
- [ :file_store, "#{root}/tmp/cache/" ]
- else
- :memory_store
+ private
+
+ def method_missing(name, *args, &blk)
+ if name.to_s =~ config_key_regexp
+ return $2 == '=' ? options[$1] = args.first : options[$1]
end
+ super
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
+ def config_key_regexp
+ bits = config_keys.map { |n| Regexp.escape(n.to_s) }.join('|')
+ /^(#{bits})(?:=)?$/
end
- end
- 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
-
- def time_zone
- @time_zone ||= "UTC"
- end
-
- def i18n
- @i18n ||= begin
- i18n = ActiveSupport::OrderedOptions.new
- i18n.load_path = []
-
- if File.exist?(File.join(root, 'config', 'locales'))
- i18n.load_path << Dir[File.join(root, 'config', 'locales', '*.{rb,yml}')]
- i18n.load_path.flatten!
- end
-
- i18n
+ def config_keys
+ (Railtie.railtie_names + Engine.engine_names).map { |n| n.to_s }.uniq
end
- end
- def environment_path
- "#{root}/config/environments/#{Rails.env}.rb"
- end
-
- # Holds generators configuration:
- #
- # config.generators do |g|
- # g.orm :datamapper, :migration => true
- # g.template_engine :haml
- # g.test_framework :rspec
- # end
- #
- # If you want to disable color in console, do:
- #
- # config.generators.colorize_logging = false
- #
- def generators
- @generators ||= Generators.new
- if block_given?
- yield @generators
- else
- @generators
+ def options
+ @@options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }
end
end
- # Allow Notifications queue to be modified or add subscriptions:
- #
- # config.notifications.queue = MyNewQueue.new
- #
- # config.notifications.subscribe /action_dispatch.show_exception/ do |*args|
- # ExceptionDeliver.deliver_exception(args)
- # end
- #
- def notifications
- ActiveSupport::Notifications
- end
-
class Generators #:nodoc:
attr_accessor :aliases, :options, :colorize_logging
@@ -319,5 +107,74 @@ module Rails
end
end
end
+
+ module Deprecated
+ def frameworks(*args)
+ raise "config.frameworks in no longer supported. See the generated " \
+ "config/boot.rb for steps on how to limit the frameworks that " \
+ "will be loaded"
+ end
+ alias :frameworks= :frameworks
+
+ 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
+ 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 log_path
+ ActiveSupport::Deprecation.warn "config.log_path is deprecated, " <<
+ "please do config.paths.log instead", caller
+ paths.config.log.to_a.first
+ end
+
+ def controller_paths=(value)
+ ActiveSupport::Deprecation.warn "config.controller_paths= is deprecated, " <<
+ "please do config.paths.app.controllers= instead", caller
+ paths.app.controllers = value
+ end
+
+ def controller_paths
+ ActiveSupport::Deprecation.warn "config.controller_paths is deprecated, " <<
+ "please do config.paths.app.controllers instead", caller
+ paths.app.controllers.to_a.uniq
+ end
+ end
end
end
diff --git a/railties/lib/rails/console_app.rb b/railties/lib/rails/console/app.rb
index 2c4a7a51e8..7e8fd027e6 100644
--- a/railties/lib/rails/console_app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -23,10 +23,11 @@ def new_session
session
end
-#reloads the environment
-def reload!
- puts "Reloading..."
- ActionDispatch::Callbacks.new(lambda {}, true)
- Rails.application.reload_routes!
+# reloads the environment
+def reload!(print=true)
+ puts "Reloading..." if print
+ ActionDispatch::Callbacks.new(lambda {}, false)
true
end
+
+reload!(false)
diff --git a/railties/lib/rails/console_with_helpers.rb b/railties/lib/rails/console/helpers.rb
index 039db667c4..039db667c4 100644
--- a/railties/lib/rails/console_with_helpers.rb
+++ b/railties/lib/rails/console/helpers.rb
diff --git a/railties/lib/rails/console_sandbox.rb b/railties/lib/rails/console/sandbox.rb
index 65a3d68619..65a3d68619 100644
--- a/railties/lib/rails/console_sandbox.rb
+++ b/railties/lib/rails/console/sandbox.rb
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
new file mode 100644
index 0000000000..e40052e0f1
--- /dev/null
+++ b/railties/lib/rails/engine.rb
@@ -0,0 +1,128 @@
+require 'active_support/core_ext/module/delegation'
+require 'rails/railtie'
+
+module Rails
+ class Engine < Railtie
+ autoload :Configurable, "rails/engine/configurable"
+ autoload :Configuration, "rails/engine/configuration"
+
+ class << self
+ attr_accessor :called_from
+
+ alias :engine_name :railtie_name
+ alias :engine_names :railtie_names
+
+ def inherited(base)
+ unless abstract_railtie?(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
+ end
+
+ super
+ end
+
+ def find_root_with_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 :middleware, :paths, :root, :to => :config
+
+ def load_tasks
+ super
+ config.paths.lib.tasks.to_a.sort.each { |ext| load(ext) }
+ end
+
+ # Add configured load paths to ruby load paths and remove duplicates.
+ initializer :set_load_path do
+ config.load_paths.reverse_each do |path|
+ $LOAD_PATH.unshift(path) if File.directory?(path)
+ end
+ $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 |app|
+ ActiveSupport::Dependencies.load_paths.concat(config.load_paths)
+
+ if reloadable?(app)
+ ActiveSupport::Dependencies.load_once_paths.concat(config.load_once_paths)
+ else
+ ActiveSupport::Dependencies.load_once_paths.concat(config.load_paths)
+ end
+
+ # Freeze so future modifications will fail rather than do nothing mysteriously
+ config.load_paths.freeze
+ config.load_once_paths.freeze
+ end
+
+ initializer :add_routing_paths do
+ paths.config.routes.to_a.each do |route|
+ Rails::Application::RoutesReloader.paths.unshift(route) if File.exists?(route)
+ end
+ end
+
+ initializer :add_routing_namespaces do |app|
+ paths.app.controllers.to_a.each do |load_path|
+ load_path = File.expand_path(load_path)
+ Dir["#{load_path}/*/*_controller.rb"].collect do |path|
+ namespace = File.dirname(path).sub(/#{load_path}\/?/, '')
+ app.routes.controller_namespaces << namespace unless namespace.empty?
+ end
+ end
+ end
+
+ initializer :add_locales do
+ config.i18n.load_path.unshift(*paths.config.locales.to_a)
+ end
+
+ initializer :add_view_paths do
+ views = paths.app.views.to_a
+ ActionController::Base.view_paths.concat(views) if defined?(ActionController)
+ ActionMailer::Base.view_paths.concat(views) if defined?(ActionMailer)
+ end
+
+ initializer :add_metals do
+ Rails::Rack::Metal.paths.concat(paths.app.metals.to_a)
+ end
+
+ initializer :load_application_initializers do
+ paths.config.initializers.to_a.sort.each do |initializer|
+ load(initializer)
+ end
+ end
+
+ 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
+
+ protected
+
+ def reloadable?(app)
+ app.config.reload_plugins
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/engine/configurable.rb b/railties/lib/rails/engine/configurable.rb
new file mode 100644
index 0000000000..9a370f0abb
--- /dev/null
+++ b/railties/lib/rails/engine/configurable.rb
@@ -0,0 +1,25 @@
+module Rails
+ class Engine
+ module Configurable
+ def self.included(base)
+ base.extend ClassMethods
+ end
+
+ module ClassMethods
+ delegate :middleware, :root, :paths, :to => :config
+
+ def config
+ @config ||= Engine::Configuration.new(find_root_with_flag("lib"))
+ end
+
+ def inherited(base)
+ raise "You cannot inherit from a Rails::Engine child"
+ end
+ end
+
+ def config
+ self.class.config
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
new file mode 100644
index 0000000000..a328e14170
--- /dev/null
+++ b/railties/lib/rails/engine/configuration.rb
@@ -0,0 +1,49 @@
+require 'rails/railtie/configuration'
+
+module Rails
+ class Engine
+ class Configuration < ::Rails::Railtie::Configuration
+ attr_reader :root
+ attr_writer :eager_load_paths, :load_once_paths, :load_paths
+
+ def initialize(root=nil)
+ @root = root
+ end
+
+ def paths
+ @paths ||= begin
+ paths = Rails::Paths::Root.new(@root)
+ paths.app "app", :eager_load => true, :glob => "*"
+ paths.app.controllers "app/controllers", :eager_load => true
+ paths.app.helpers "app/helpers", :eager_load => true
+ paths.app.metals "app/metal"
+ paths.app.views "app/views"
+ paths.lib "lib", :load_path => true
+ paths.lib.tasks "lib/tasks", :glob => "**/*.rake"
+ paths.config "config"
+ paths.config.environment "config/environments", :glob => "#{Rails.env}.rb"
+ paths.config.initializers "config/initializers", :glob => "**/*.rb"
+ paths.config.locales "config/locales", :glob => "*.{rb,yml}"
+ paths.config.routes "config/routes.rb"
+ paths
+ end
+ end
+
+ def root=(value)
+ @root = paths.path = Pathname.new(value).expand_path
+ 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
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index 8fcb254590..cea4a0fdf7 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -19,12 +19,6 @@ module Rails
@options[:after]
end
- def global
- @options[:global]
- end
-
- alias global? global
-
def run(*args)
@context.instance_exec(*args, &block)
end
@@ -71,7 +65,7 @@ module Rails
def initializers
@initializers ||= begin
- initializers = self.class.initializers_for(:instance)
+ initializers = self.class.initializers_chain
Collection.new(initializers.map { |i| i.bind(self) })
end
end
@@ -81,26 +75,23 @@ module Rails
@initializers ||= []
end
- def initializers_for(scope = :global)
+ def initializers_chain
initializers = Collection.new
ancestors.reverse_each do |klass|
next unless klass.respond_to?(:initializers)
- initializers = initializers + klass.initializers.select { |i|
- (scope == :global) == !!i.global?
- }
+ initializers = initializers + klass.initializers
end
initializers
end
def initializer(name, opts = {}, &blk)
raise ArgumentError, "A block must be passed when defining an initializer" unless blk
- @initializers ||= []
- @initializers << Initializer.new(name, nil, opts, &blk)
+ initializers << Initializer.new(name, nil, opts, &blk)
end
def run_initializers(*args)
return if @ran
- initializers_for(:global).each do |initializer|
+ initializers_chain.each do |initializer|
instance_exec(*args, &initializer.block)
end
@ran = true
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index b3d105d8c7..55874813da 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -1,7 +1,7 @@
require 'set'
module Rails
- class Application
+ module Paths
module PathParent
def method_missing(id, *args)
name = id.to_s
@@ -31,27 +31,21 @@ module Rails
@all_paths = []
end
- def load_once
- all_paths.map { |path| path.paths if path.load_once? }.compact.flatten.uniq
- end
-
- def eager_load
- all_paths.map { |path| path.paths if path.eager_load? }.compact.flatten.uniq
- end
-
def all_paths
@all_paths.uniq!
@all_paths
end
- def load_paths
- all_paths.map { |path| path.paths if path.load_path? }.compact.flatten.uniq
+ def load_once
+ filter { |path| path.paths if path.load_once? }
end
- def add_to_load_path
- load_paths.reverse_each do |path|
- $LOAD_PATH.unshift(path) if File.directory?(path)
- end
+ def eager_load
+ filter { |path| path.paths if path.eager_load? }
+ end
+
+ def load_paths
+ filter { |path| path.paths if path.load_path? }
end
def push(*)
@@ -61,6 +55,12 @@ module Rails
alias unshift push
alias << push
alias concat push
+
+ protected
+
+ def filter(&block)
+ all_paths.map(&block).compact.flatten.uniq.select { |p| File.exists?(p) }
+ end
end
class Path
@@ -74,11 +74,11 @@ module Rails
@children = {}
@root = root
@paths = paths.flatten
- @glob = @options[:glob] || "**/*.rb"
+ @glob = @options.delete(:glob)
@load_once = @options[:load_once]
@eager_load = @options[:eager_load]
- @load_path = @options[:load_path] || @eager_load
+ @load_path = @options[:load_path] || @eager_load || @load_once
@root.all_paths << self
end
@@ -103,6 +103,7 @@ module Rails
def load_once!
@load_once = true
+ @load_path = true
end
def load_once?
@@ -128,10 +129,13 @@ module Rails
def paths
raise "You need to set a path root" unless @root.path
-
- @paths.map do |path|
- path.index('/') == 0 ? path : File.expand_path(File.join(@root.path, path))
+ result = @paths.map do |p|
+ path = File.expand_path(p, @root.path)
+ @glob ? Dir[File.join(path, @glob)] : path
end
+ result.flatten!
+ result.uniq!
+ result
end
alias to_a paths
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index c3b81bcd3e..4c73809177 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -1,5 +1,11 @@
+require 'rails/engine'
+
module Rails
- class Plugin < Railtie
+ class Plugin < Engine
+ def self.inherited(base)
+ raise "You cannot inherit from Rails::Plugin"
+ end
+
def self.all(list, paths)
plugins = []
paths.each do |path|
@@ -17,52 +23,35 @@ module Rails
attr_reader :name, :path
- def initialize(path)
- @name = File.basename(path).to_sym
- @path = path
- end
+ def load_tasks
+ super
+ extra_tasks = Dir["#{root}/{tasks,rails/tasks}/**/*.rake"]
- def load_paths
- Dir["#{path}/{lib}", "#{path}/app/{models,controllers,helpers}"]
+ unless extra_tasks.empty?
+ ActiveSupport::Deprecation.warn "Having rake tasks in PLUGIN_PATH/tasks or " <<
+ "PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead"
+ extra_tasks.sort.each { |ext| load(ext) }
+ end
end
- def load_tasks
- Dir["#{path}/{tasks,lib/tasks,rails/tasks}/**/*.rake"].sort.each { |ext| load ext }
+ def initialize(root)
+ @name = File.basename(root).to_sym
+ config.root = root
end
- initializer :add_to_load_path, :after => :set_autoload_paths do |app|
- load_paths.each do |path|
- $LOAD_PATH << path
- require "active_support/dependencies"
-
- ActiveSupport::Dependencies.load_paths << path
-
- unless app.config.reload_plugins
- ActiveSupport::Dependencies.load_once_paths << path
- end
- end
+ def config
+ @config ||= Engine::Configuration.new
end
- initializer :load_init_rb, :before => :load_application_initializers do |app|
- file = "#{@path}/init.rb"
+ initializer :load_init_rb do |app|
+ file = Dir["#{root}/{rails/init,init}.rb"].first
config = app.config
- eval File.read(file), binding, file if File.file?(file)
- end
-
- initializer :add_view_paths, :after => :initialize_framework_views do
- plugin_views = "#{path}/app/views"
- if File.directory?(plugin_views)
- ActionController::Base.view_paths.concat([plugin_views]) if defined? ActionController
- ActionMailer::Base.view_paths.concat([plugin_views]) if defined? ActionMailer
- end
+ eval(File.read(file), binding, file) if file && File.file?(file)
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)
- app.route_configuration_files << routing_file
- app.reload_routes!
+ initializer :sanity_check_railties_collision do
+ if Engine.subclasses.map { |k| k.root.to_s }.include?(root.to_s)
+ raise "\"#{name}\" is a Railtie/Engine and cannot be installed as plugin"
end
end
end
diff --git a/railties/lib/rails/rack/metal.rb b/railties/lib/rails/rack/metal.rb
index 565f95d7c4..732936da32 100644
--- a/railties/lib/rails/rack/metal.rb
+++ b/railties/lib/rails/rack/metal.rb
@@ -3,14 +3,29 @@ require 'action_dispatch'
module Rails
module Rack
class Metal
- def initialize(metal_roots, metals=nil)
- load_list = metals || Dir["{#{metal_roots.join(",")}}/**/*.rb"]
+ def self.paths
+ @paths ||= []
+ end
+
+ def initialize(list=nil)
+ metals = []
+ list = Array(list || :all).map(&:to_sym)
+
+ self.class.paths.each do |path|
+ matcher = /\A#{Regexp.escape(path)}\/(.*)\.rb\Z/
+ Dir.glob("#{path}/**/*.rb").sort.each do |metal_path|
+ metal = metal_path.sub(matcher, '\1').to_sym
+ next unless list.include?(metal) || list.include?(:all)
+ require_dependency metal
+ metals << metal
+ end
+ end
+
+ metals = metals.sort_by do |m|
+ [list.index(m) || list.index(:all), m.to_s]
+ end
- @metals = load_list.map { |metal|
- metal = File.basename(metal, '.rb')
- require_dependency metal
- metal.camelize.constantize
- }.compact
+ @metals = metals.map { |m| m.to_s.camelize.constantize }
end
def new(app)
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index e3297148e5..3cf358d75f 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -1,44 +1,66 @@
+require 'rails/initializable'
+require 'rails/configuration'
+
module Rails
class Railtie
+ autoload :Configurable, "rails/railtie/configurable"
+ autoload :Configuration, "rails/railtie/configuration"
+
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 subclasses
+ @subclasses ||= []
+ end
- def self.plugins
- @plugins
- end
+ def inherited(base)
+ unless abstract_railtie?(base)
+ base.send(:include, self::Configurable) if add_configurable?(base)
+ subclasses << base
+ end
+ end
- def self.plugin_names
- plugins.map { |p| p.plugin_name }
- end
+ def railtie_name(railtie_name = nil)
+ @railtie_name ||= name.demodulize.underscore
+ @railtie_name = railtie_name if railtie_name
+ @railtie_name
+ end
- def self.config
- Configuration.default
- end
+ def railtie_names
+ subclasses.map { |p| p.railtie_name }
+ end
- def self.subscriber(subscriber)
- Rails::Subscriber.add(plugin_name, subscriber)
- end
+ def subscriber(subscriber)
+ Rails::Subscriber.add(railtie_name, subscriber)
+ end
- def self.rake_tasks(&blk)
- @rake_tasks ||= []
- @rake_tasks << blk if blk
- @rake_tasks
- end
+ def rake_tasks(&blk)
+ @rake_tasks ||= []
+ @rake_tasks << blk if blk
+ @rake_tasks
+ end
+
+ def generators(&blk)
+ @generators ||= []
+ @generators << blk if blk
+ @generators
+ end
+
+ protected
+
+ def abstract_railtie?(base)
+ ABSTRACT_RAILTIES.include?(base.name)
+ end
- def self.generators(&blk)
- @generators ||= []
- @generators << blk if blk
- @generators
+ # Just add configurable behavior if a Configurable module is defined
+ # and the class is a direct child from self. This is required to avoid
+ # application or plugins getting class configuration method from Railties
+ # and/or Engines.
+ def add_configurable?(base)
+ defined?(self::Configurable) && base.ancestors[1] == self
+ end
end
def rake_tasks
@@ -50,12 +72,10 @@ module Rails
end
def load_tasks
- return unless rake_tasks
rake_tasks.each { |blk| blk.call }
end
def load_generators
- return unless generators
generators.each { |blk| blk.call }
end
end
diff --git a/railties/lib/rails/railtie/configurable.rb b/railties/lib/rails/railtie/configurable.rb
new file mode 100644
index 0000000000..a2eb938c5a
--- /dev/null
+++ b/railties/lib/rails/railtie/configurable.rb
@@ -0,0 +1,23 @@
+module Rails
+ class Railtie
+ module Configurable
+ def self.included(base)
+ base.extend ClassMethods
+ end
+
+ module ClassMethods
+ def config
+ @config ||= Railtie::Configuration.new
+ end
+
+ def inherited(base)
+ raise "You cannot inherit from a Rails::Railtie child"
+ end
+ end
+
+ def config
+ self.class.config
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/railtie/configuration.rb b/railties/lib/rails/railtie/configuration.rb
new file mode 100644
index 0000000000..bfb43f7041
--- /dev/null
+++ b/railties/lib/rails/railtie/configuration.rb
@@ -0,0 +1,9 @@
+require 'rails/configuration'
+
+module Rails
+ class Railtie
+ class Configuration
+ include Rails::Configuration::Shared
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake
index 65d0d476ba..3f49a9a720 100644
--- a/railties/lib/rails/tasks/documentation.rake
+++ b/railties/lib/rails/tasks/documentation.rake
@@ -11,35 +11,43 @@ namespace :doc do
rdoc.rdoc_files.include('lib/**/*.rb')
}
- desc "Generate documentation for the Rails framework"
+ desc 'Generate documentation for the Rails framework. Specify path with PATH="/path/to/rails"'
Rake::RDocTask.new("rails") { |rdoc|
+ path = ENV['RAILS_PATH'] || 'vendor/gems/gems'
+ version = '-3.0.pre' unless ENV['RAILS_PATH']
rdoc.rdoc_dir = 'doc/api'
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
rdoc.title = "Rails Framework Documentation"
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('vendor/rails/railties/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/railties/MIT-LICENSE')
- rdoc.rdoc_files.include('vendor/rails/railties/README')
- rdoc.rdoc_files.include('vendor/rails/railties/lib/{*.rb,commands/*.rb,generators/*.rb}')
- rdoc.rdoc_files.include('vendor/rails/activerecord/README')
- rdoc.rdoc_files.include('vendor/rails/activerecord/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/activerecord/lib/active_record/**/*.rb')
- rdoc.rdoc_files.exclude('vendor/rails/activerecord/lib/active_record/vendor/*')
- rdoc.rdoc_files.include('vendor/rails/activeresource/README')
- rdoc.rdoc_files.include('vendor/rails/activeresource/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/activeresource/lib/active_resource.rb')
- rdoc.rdoc_files.include('vendor/rails/activeresource/lib/active_resource/*')
- rdoc.rdoc_files.include('vendor/rails/actionpack/README')
- rdoc.rdoc_files.include('vendor/rails/actionpack/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_controller/**/*.rb')
- rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_view/**/*.rb')
- rdoc.rdoc_files.include('vendor/rails/actionmailer/README')
- rdoc.rdoc_files.include('vendor/rails/actionmailer/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/actionmailer/lib/action_mailer/base.rb')
- rdoc.rdoc_files.include('vendor/rails/activesupport/README')
- rdoc.rdoc_files.include('vendor/rails/activesupport/CHANGELOG')
- rdoc.rdoc_files.include('vendor/rails/activesupport/lib/active_support/**/*.rb')
+
+ %w(README CHANGELOG lib/action_mailer/base.rb).each do |file|
+ rdoc.rdoc_files.include("#{path}/actionmailer#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG lib/action_controller/**/*.rb lib/action_view/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{path}/actionpack#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG lib/active_model/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{path}/activemodel#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG lib/active_record/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{path}/activerecord#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG lib/active_resource.rb lib/active_resource/*).each do |file|
+ rdoc.rdoc_files.include("#{path}/activeresource#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG lib/active_support/**/*.rb).each do |file|
+ rdoc.rdoc_files.include("#{path}/activesupport#{version}/#{file}")
+ end
+
+ %w(README CHANGELOG MIT-LICENSE lib/{*.rb,commands/*.rb,generators/*.rb}).each do |file|
+ rdoc.rdoc_files.include("#{path}/railties#{version}/#{file}")
+ end
}
plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) }
diff --git a/railties/lib/rails/tasks/middleware.rake b/railties/lib/rails/tasks/middleware.rake
index 5a5bd7a7e9..c3aaddb153 100644
--- a/railties/lib/rails/tasks/middleware.rake
+++ b/railties/lib/rails/tasks/middleware.rake
@@ -3,5 +3,5 @@ task :middleware => :environment do
Rails.configuration.middleware.active.each do |middleware|
puts "use #{middleware.inspect}"
end
- puts "run #{Rails.application.class.name}"
+ puts "run #{Rails::Application.class.name}"
end
diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake
index 2395d73b2f..e8da72db4d 100644
--- a/railties/lib/rails/tasks/routes.rake
+++ b/railties/lib/rails/tasks/routes.rake
@@ -1,5 +1,6 @@
desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.'
task :routes => :environment do
+ Rails::Application.reload_routes!
all_routes = ENV['CONTROLLER'] ? ActionController::Routing::Routes.routes.select { |route| route.defaults[:controller] == ENV['CONTROLLER'] } : ActionController::Routing::Routes.routes
routes = all_routes.collect do |route|
name = ActionController::Routing::Routes.named_routes.routes.index(route).to_s