diff options
Diffstat (limited to 'railties/lib/rails/engine.rb')
-rw-r--r-- | railties/lib/rails/engine.rb | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 1dede32dd4..2dd1fb3273 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -1,7 +1,8 @@ -require 'rails/railtie' -require 'rails/engine/railties' -require 'active_support/core_ext/module/delegation' -require 'pathname' +require "rails/railtie" +require "rails/engine/railties" +require "active_support/core_ext/module/delegation" +require "pathname" +require "thread" module Rails # <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of @@ -218,7 +219,7 @@ module Rails # The next thing that changes in isolated engines is the behavior of routes. # Normally, when you namespace your controllers, you also need to namespace # the related routes. With an isolated engine, the engine's namespace is - # automatically applied, so you don't need to specify it explicity in your + # automatically applied, so you don't need to specify it explicitly in your # routes: # # MyEngine::Engine.routes.draw do @@ -336,7 +337,7 @@ module Rails # == Loading priority # # In order to change engine's priority you can use +config.railties_order+ in the main application. - # It will affect the priority of loading views, helpers, assets and all the other files + # It will affect the priority of loading views, helpers, assets, and all the other files # related to engine or application. # # # load Blog::Engine with highest priority, followed by application and other railties @@ -357,12 +358,7 @@ module Rails Rails::Railtie::Configuration.eager_load_namespaces << base base.called_from = begin - call_stack = if Kernel.respond_to?(:caller_locations) - caller_locations.map { |l| l.absolute_path || l.path } - else - # Remove the line number from backtraces making sure we don't leave anything behind - caller.map { |p| p.sub(/:\d+.*/, '') } - end + call_stack = caller_locations.map { |l| l.absolute_path || l.path } File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] }) end @@ -406,7 +402,7 @@ module Rails end unless mod.respond_to?(:railtie_routes_url_helpers) - define_method(:railtie_routes_url_helpers) {|include_path_helpers = true| railtie.routes.url_helpers(include_path_helpers) } + define_method(:railtie_routes_url_helpers) { |include_path_helpers = true| railtie.routes.url_helpers(include_path_helpers) } end end end @@ -434,12 +430,13 @@ module Rails @env_config = nil @helpers = nil @routes = nil + @app_build_lock = Mutex.new super end # Load console and invoke the registered hooks. # Check <tt>Rails::Railtie.console</tt> for more info. - def load_console(app=self) + def load_console(app = self) require "rails/console/app" require "rails/console/helpers" run_console_blocks(app) @@ -448,14 +445,14 @@ module Rails # Load Rails runner and invoke the registered hooks. # Check <tt>Rails::Railtie.runner</tt> for more info. - def load_runner(app=self) + def load_runner(app = self) run_runner_blocks(app) self end # Load Rake, railties tasks and invoke the registered hooks. # Check <tt>Rails::Railtie.rake_tasks</tt> for more info. - def load_tasks(app=self) + def load_tasks(app = self) require "rake" run_tasks_blocks(app) self @@ -463,7 +460,7 @@ module Rails # Load Rails generators and invoke the registered hooks. # Check <tt>Rails::Railtie.generators</tt> for more info. - def load_generators(app=self) + def load_generators(app = self) require "rails/generators" run_generators_blocks(app) Rails::Generators.configure!(app.config.generators) @@ -504,10 +501,13 @@ module Rails # Returns the underlying rack application for this engine. def app - @app ||= begin - config.middleware = config.middleware.merge_into(default_middleware_stack) - config.middleware.build(endpoint) - end + @app || @app_build_lock.synchronize { + @app ||= begin + stack = default_middleware_stack + config.middleware = build_middleware.merge_into(stack) + config.middleware.build(endpoint) + end + } end # Returns the endpoint for this engine. If none is registered, @@ -518,18 +518,13 @@ module Rails # Define the Rack API for this engine. def call(env) - env.merge!(env_config) - if env['SCRIPT_NAME'] - env[routes.env_key] = env['SCRIPT_NAME'].dup - end - app.call(env) + req = build_request env + app.call req.env end # Defines additional Rack env configuration that is added on each call. def env_config - @env_config ||= { - 'action_dispatch.routes' => routes - } + @env_config ||= {} end # Defines the routes for this engine. If a block is given to @@ -589,14 +584,14 @@ module Rails # I18n load paths are a special case since the ones added # later have higher priority. initializer :add_locales do - config.i18n.railties_load_path.concat(paths["config/locales"].existent) + config.i18n.railties_load_path << paths["config/locales"] end initializer :add_view_paths do views = paths["app/views"].existent unless views.empty? - ActiveSupport.on_load(:action_controller){ prepend_view_path(views) if respond_to?(:prepend_view_path) } - ActiveSupport.on_load(:action_mailer){ prepend_view_path(views) } + ActiveSupport.on_load(:action_controller) { prepend_view_path(views) if respond_to?(:prepend_view_path) } + ActiveSupport.on_load(:action_mailer) { prepend_view_path(views) } end end @@ -624,7 +619,7 @@ module Rails end rake_tasks do - next if self.is_a?(Rails::Application) + next if is_a?(Rails::Application) next unless has_migrations? namespace railtie_name do @@ -648,48 +643,62 @@ module Rails protected - def load_config_initializer(initializer) - ActiveSupport::Notifications.instrument('load_config_initializer.railties', initializer: initializer) do - load(initializer) + def run_tasks_blocks(*) #:nodoc: + super + paths["lib/tasks"].existent.sort.each { |ext| load(ext) } end - end - def run_tasks_blocks(*) #:nodoc: - super - paths["lib/tasks"].existent.sort.each { |ext| load(ext) } - end + private - def has_migrations? #:nodoc: - paths["db/migrate"].existent.any? - end + def load_config_initializer(initializer) # :doc: + ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do + load(initializer) + end + end + + def has_migrations? + paths["db/migrate"].existent.any? + end + + def self.find_root_with_flag(flag, root_path, default = nil) #:nodoc: + + while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}") + parent = File.dirname(root_path) + root_path = parent != root_path && parent + end - def self.find_root_with_flag(flag, root_path, default=nil) #:nodoc: + root = File.exist?("#{root_path}/#{flag}") ? root_path : default + raise "Could not find root path for #{self}" unless root - while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}") - parent = File.dirname(root_path) - root_path = parent != root_path && parent + Pathname.new File.realpath root end - root = File.exist?("#{root_path}/#{flag}") ? root_path : default - raise "Could not find root path for #{self}" unless root + def default_middleware_stack + ActionDispatch::MiddlewareStack.new + end - Pathname.new File.realpath root - end + def _all_autoload_once_paths + config.autoload_once_paths + end - def default_middleware_stack #:nodoc: - ActionDispatch::MiddlewareStack.new - end + def _all_autoload_paths + @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq + end - def _all_autoload_once_paths #:nodoc: - config.autoload_once_paths - end + def _all_load_paths + @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq + end - def _all_autoload_paths #:nodoc: - @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq - end + def build_request(env) + env.merge!(env_config) + req = ActionDispatch::Request.new env + req.routes = routes + req.engine_script_name = req.script_name + req + end - def _all_load_paths #:nodoc: - @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq - end + def build_middleware + config.middleware + end end end |