diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index d69e3eea6aa20756d93e15164fd9e0da7b71a273..41672325bd287d1456fb1e6b606c75bfdd32b410 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -32,6 +32,8 @@ RAILS_ENV = (ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development").dup unless defined?(RAILS_ENV) module Rails + autoload :Bootstrap, 'rails/bootstrap' + # Needs to be duplicated from Active Support since its needed before Active # Support is available. Here both Options and Hash are namespaced to prevent # conflicts with other implementations AND with the classes residing in Active Support. diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index b3b48194d4f9884086636ed5dc006f1c1384d010..6034aa8485fbba3ee72b2d4744f52c8e81f5515f 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -83,8 +83,9 @@ def load_tasks end def initializers - initializers = super + initializers = Bootstrap.new(self).initializers plugins.each { |p| initializers += p.initializers } + initializers += super initializers end @@ -103,135 +104,6 @@ def call(env) @app.call(env) end - initializer :load_all_active_support do - require "active_support/all" unless config.active_support.bare - end - - # Set the $LOAD_PATH 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 = config.load_paths.uniq - ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq - - 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 - # if the environment has explicitly defined a logger, use it - next if Rails.logger - - unless logger = config.logger - begin - logger = ActiveSupport::BufferedLogger.new(config.log_path) - logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase) - if RAILS_ENV == "production" - logger.auto_flushing = false - end - 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." - ) - end - end - - # TODO: Why are we silencing warning here? - silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } - end - - # Sets the logger for Active Record, Action Controller, and Action Mailer - # (but only for those frameworks that are to be loaded). If the framework's - # logger is already set, it is not changed, otherwise it is set to use - # RAILS_DEFAULT_LOGGER. - 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 - config.i18n.each do |setting, value| - if setting == :load_path - I18n.load_path += value - else - I18n.send("#{setting}=", value) - end - end - end - # # bail out if gems are missing - note that check_gem_dependencies will have # # already called abort() unless $gems_rake_task is set # return unless gems_dependencies_loaded diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb new file mode 100644 index 0000000000000000000000000000000000000000..15d5b2b59dd897cf0eaecc82c1f642d3d6e296cc --- /dev/null +++ b/railties/lib/rails/bootstrap.rb @@ -0,0 +1,140 @@ +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 $LOAD_PATH 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 = config.load_paths.uniq + ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq + + 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 + # if the environment has explicitly defined a logger, use it + next if Rails.logger + + unless logger = config.logger + begin + logger = ActiveSupport::BufferedLogger.new(config.log_path) + logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase) + if RAILS_ENV == "production" + logger.auto_flushing = false + end + 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." + ) + end + end + + # TODO: Why are we silencing warning here? + silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } + end + + # Sets the logger for Active Record, Action Controller, and Action Mailer + # (but only for those frameworks that are to be loaded). If the framework's + # logger is already set, it is not changed, otherwise it is set to use + # RAILS_DEFAULT_LOGGER. + 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 + config.i18n.each do |setting, value| + if setting == :load_path + I18n.load_path += value + else + I18n.send("#{setting}=", value) + end + end + end + end +end diff --git a/railties/test/application/initializer_test.rb b/railties/test/application/initializer_test.rb index 3fd0b0e5df044f8132196626a79cc1d4329f19bf..754c0f18390dba65a1041adbde2442381d9e1bcd 100644 --- a/railties/test/application/initializer_test.rb +++ b/railties/test/application/initializer_test.rb @@ -83,6 +83,17 @@ module Zoo::ReptileHouse ; end assert_equal "congratulations", $test_after_initialize_block2 end + test "after_initialize runs after frameworks have been initialized" do + $activerecord_configurations = nil + add_to_config <<-RUBY + config.after_initialize { $activerecord_configurations = ActiveRecord::Base.configurations } + RUBY + + require "#{app_path}/config/environment" + assert $activerecord_configurations + assert $activerecord_configurations['development'] + end + # i18n test "setting another default locale" do add_to_config <<-RUBY