aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/application
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails/application')
-rw-r--r--railties/lib/rails/application/bootstrap.rb85
-rw-r--r--railties/lib/rails/application/configurable.rb19
-rw-r--r--railties/lib/rails/application/configuration.rb84
-rw-r--r--railties/lib/rails/application/finisher.rb49
-rw-r--r--railties/lib/rails/application/metal_loader.rb50
-rw-r--r--railties/lib/rails/application/railties.rb31
-rw-r--r--railties/lib/rails/application/routes_reloader.rb46
7 files changed, 364 insertions, 0 deletions
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
new file mode 100644
index 0000000000..b20e53f2de
--- /dev/null
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -0,0 +1,85 @@
+module Rails
+ class Application
+ module Bootstrap
+ include Initializable
+
+ initializer :load_environment_config do
+ require_environment!
+ end
+
+ initializer :load_all_active_support do
+ require "active_support/all" unless 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
+ require 'active_support/dependencies'
+ ActiveSupport::Autoload.eager_autoload! if config.preload_frameworks
+ end
+
+ # Initialize the logger early in the stack in case we need to log some deprecation.
+ initializer :initialize_logger do
+ Rails.logger ||= config.logger || begin
+ path = config.paths.log.to_a.first
+ logger = ActiveSupport::BufferedLogger.new(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 #{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
+ unless defined?(RAILS_CACHE)
+ silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) }
+
+ if RAILS_CACHE.respond_to?(:middleware)
+ config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
+ end
+ end
+ end
+
+ # Initialize rails subscriber on top of notifications.
+ initializer :initialize_subscriber 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
+
+ initializer :set_clear_dependencies_hook do
+ unless 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
+ ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
+ end
+
+ initializer :bootstrap_load_path do
+ # This is just an initializer used as hook so all load paths are loaded together
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/configurable.rb b/railties/lib/rails/application/configurable.rb
new file mode 100644
index 0000000000..f598e33965
--- /dev/null
+++ b/railties/lib/rails/application/configurable.rb
@@ -0,0 +1,19 @@
+module Rails
+ class Application
+ module Configurable
+ def self.included(base)
+ base.extend ClassMethods
+ end
+
+ module ClassMethods
+ def inherited(base)
+ raise "You cannot inherit from a Rails::Application child"
+ end
+ end
+
+ def config
+ @config ||= Application::Configuration.new(self.class.find_root_with_flag("config.ru", Dir.pwd))
+ 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..31787b5cc9
--- /dev/null
+++ b/railties/lib/rails/application/configuration.rb
@@ -0,0 +1,84 @@
+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_engines, :reload_plugins,
+ :serve_static_assets, :time_zone, :whiny_nils
+
+ def initialize(*)
+ super
+ @colorize_logging = true
+ @filter_parameters = []
+ @dependency_loading = true
+ @serve_static_assets = true
+ @time_zone = "UTC"
+ end
+
+ def paths
+ @paths ||= begin
+ paths = super
+ paths.app.controllers << builtin_controller if builtin_controller
+ paths.config.database "config/database.yml"
+ paths.config.environment "config/environments", :glob => "#{Rails.env}.rb"
+ 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
+ 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..b722679ec2
--- /dev/null
+++ b/railties/lib/rails/application/finisher.rb
@@ -0,0 +1,49 @@
+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_to_prepare_blocks do
+ config.to_prepare_blocks.each do |block|
+ ActionDispatch::Callbacks.to_prepare(&block)
+ end
+ end
+
+ initializer :add_builtin_route do |app|
+ if Rails.env.development?
+ app.routes_reloader.paths << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
+ end
+ end
+
+ initializer :build_middleware_stack do
+ app
+ end
+
+ # Fires the user-supplied after_initialize block (config.after_initialize)
+ initializer :after_initialize do
+ config.after_initialize_blocks.each do |block|
+ block.call(self)
+ end
+ end
+
+ # Disable dependency loading during request cycle
+ initializer :disable_dependency_loading do
+ if config.cache_classes && !config.dependency_loading
+ ActiveSupport::Dependencies.unhook!
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/application/metal_loader.rb b/railties/lib/rails/application/metal_loader.rb
new file mode 100644
index 0000000000..c0f2e4f948
--- /dev/null
+++ b/railties/lib/rails/application/metal_loader.rb
@@ -0,0 +1,50 @@
+require 'action_dispatch'
+
+module Rails
+ class Application
+ class MetalLoader
+ attr_reader :paths, :metals
+
+ def initialize
+ @paths, @metals = [], []
+ end
+
+ def build_middleware(list=nil)
+ load_metals!(list)
+ self
+ end
+
+ def new(app)
+ ActionDispatch::Cascade.new(@metals, app)
+ end
+
+ def name
+ ActionDispatch::Cascade.name
+ end
+ alias :to_s :name
+
+ protected
+
+ def load_metals!(list)
+ metals = []
+ list = Array(list || :all).map(&:to_sym)
+
+ 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 = metals.map { |m| m.to_s.camelize.constantize }
+ end
+ end
+ end
+end
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..fde6211c5d
--- /dev/null
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -0,0 +1,46 @@
+module Rails
+ class Application
+ class RoutesReloader
+ attr_reader :paths
+
+ def initialize
+ @paths, @last_change_at = [], nil
+ end
+
+ def changed_at
+ routes_changed_at = nil
+
+ 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!
+ 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