Merge branch 'master' of git://github.com/rails/rails

Conflicts:
	actionmailer/lib/action_mailer/mail_helper.rb
	railties/lib/rails/configuration.rb
This commit is contained in:
José Valim and Mikel Lindsaar 2010-01-25 09:50:01 +11:00
commit 4e96442c4e
59 changed files with 1226 additions and 926 deletions

View File

@ -3,7 +3,7 @@ require "rails"
module ActionMailer
class Railtie < Rails::Railtie
plugin_name :action_mailer
railtie_name :action_mailer
require "action_mailer/railties/subscriber"
subscriber ActionMailer::Railties::Subscriber.new
@ -18,11 +18,5 @@ module ActionMailer
initializer "action_mailer.logger" do
ActionMailer::Base.logger ||= Rails.logger
end
initializer "action_mailer.view_paths" do |app|
# TODO: this should be combined with the logic for default config.action_mailer.view_paths
view_path = ActionView::PathSet.type_cast(app.config.view_path, app.config.cache_classes)
ActionMailer::Base.template_root = view_path if ActionMailer::Base.view_paths.blank?
end
end
end

View File

@ -7,7 +7,6 @@ module ActionController
include AbstractController::Translation
include ActionController::Helpers
helper :all # By default, all helpers should be included
include ActionController::HideActions
include ActionController::UrlFor
@ -67,6 +66,7 @@ module ActionController
def self.inherited(klass)
::ActionController::Base.subclasses << klass.to_s
super
klass.helper :all
end
def self.subclasses

View File

@ -50,9 +50,8 @@ module ActionController
include AbstractController::Helpers
included do
# Set the default directory for helpers
extlib_inheritable_accessor(:helpers_dir) do
defined?(Rails.root) ? "#{Rails.root}/app/helpers" : "app/helpers"
extlib_inheritable_accessor(:helpers_path) do
defined?(Rails::Application) ? Rails::Application.paths.app.helpers.to_a : []
end
end
@ -105,10 +104,16 @@ module ActionController
raise e unless e.missing_name? "#{module_name}Helper"
end
# Extract helper names from files in app/helpers/**/*.rb
# Extract helper names from files in app/helpers/**/*_helper.rb
def all_application_helpers
extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/
Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
helpers = []
helpers_path.each do |path|
extract = /^#{Regexp.quote(path)}\/?(.*)_helper.rb$/
helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
helpers.sort!
helpers.uniq!
helpers
end
end
end

View File

@ -3,7 +3,7 @@ require "rails"
module ActionController
class Railtie < Rails::Railtie
plugin_name :action_controller
railtie_name :action_controller
require "action_controller/railties/subscriber"
subscriber ActionController::Railties::Subscriber.new
@ -19,25 +19,8 @@ module ActionController
ActionController::Base.logger ||= Rails.logger
end
# Routing must be initialized after plugins to allow the former to extend the routes
initializer "action_controller.initialize_routing" do |app|
app.route_configuration_files << app.config.routes_configuration_file
app.route_configuration_files << app.config.builtin_routes_configuration_file
end
initializer "action_controller.initialize_framework_caches" do
ActionController::Base.cache_store ||= RAILS_CACHE
end
# Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
# (but only for those frameworks that are to be loaded). If the framework's
# paths have already been set, it is not changed, otherwise it is
# set to use Configuration#view_path.
initializer "action_controller.initialize_framework_views" do |app|
# TODO: this should be combined with the logic for default config.action_controller.view_paths
view_path = ActionView::PathSet.type_cast(app.config.view_path, app.config.cache_classes)
ActionController::Base.view_paths = view_path if ActionController::Base.view_paths.blank?
end
end
end

View File

@ -37,7 +37,7 @@ module ActionDispatch
def initialize(app, prepare_each_request = false)
@app, @prepare_each_request = app, prepare_each_request
run_callbacks(:prepare)
run_callbacks(:prepare) unless @prepare_each_request
end
def call(env)

View File

@ -3,24 +3,13 @@ require "rails"
module ActionDispatch
class Railtie < Rails::Railtie
plugin_name :action_dispatch
railtie_name :action_dispatch
# Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_dispatch.prepare_dispatcher" do |app|
# TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
require 'rails/dispatcher'
unless app.config.cache_classes
# Setup dev mode route reloading
routes_last_modified = app.routes_changed_at
reload_routes = lambda do
unless app.routes_changed_at == routes_last_modified
routes_last_modified = app.routes_changed_at
app.reload_routes!
end
end
ActionDispatch::Callbacks.before { |callbacks| reload_routes.call }
end
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.reload_if_changed }
end
end
end

View File

@ -222,19 +222,18 @@ module ActionDispatch
end
end
attr_accessor :routes, :named_routes
attr_accessor :disable_clear_and_finalize
attr_accessor :routes, :named_routes, :controller_namespaces
attr_accessor :disable_clear_and_finalize, :resources_path_names
def self.default_resources_path_names
{ :new => 'new', :edit => 'edit' }
end
attr_accessor :resources_path_names
def initialize
self.routes = []
self.named_routes = NamedRouteCollection.new
self.resources_path_names = self.class.default_resources_path_names
self.resources_path_names = self.class.default_resources_path_names.dup
self.controller_namespaces = Set.new
@disable_clear_and_finalize = false
end
@ -281,32 +280,19 @@ module ActionDispatch
def controller_constraints
@controller_constraints ||= begin
source = controller_namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" }
namespaces = controller_namespaces + in_memory_controller_namespaces
source = namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" }
source << CONTROLLER_REGEXP.source
Regexp.compile(source.sort.reverse.join('|'))
end
end
def controller_namespaces
def in_memory_controller_namespaces
namespaces = Set.new
# Find any nested controllers already in memory
ActionController::Base.subclasses.each do |klass|
controller_name = klass.underscore
namespaces << controller_name.split('/')[0...-1].join('/')
end
# TODO: Move this into Railties
if defined?(Rails.application)
# Find namespaces in controllers/ directory
Rails.application.config.controller_paths.each do |load_path|
load_path = File.expand_path(load_path)
Dir["#{load_path}/**/*_controller.rb"].collect do |path|
namespaces << File.dirname(path).sub(/#{load_path}\/?/, '')
end
end
end
namespaces.delete('')
namespaces
end

View File

@ -3,7 +3,7 @@ require "rails"
module ActionView
class Railtie < Rails::Railtie
plugin_name :action_view
railtie_name :action_view
require "action_view/railties/subscriber"
subscriber ActionView::Railties::Subscriber.new

View File

@ -1,6 +1,6 @@
require 'abstract_unit'
ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers'
ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
module AbstractController
module Testing

View File

@ -1,7 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/kernel/reporting'
ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers'
ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
module Fun
class GamesController < ActionController::Base
@ -106,7 +106,7 @@ class HelperTest < Test::Unit::TestCase
end
def test_all_helpers_with_alternate_helper_dir
@controller_class.helpers_dir = File.dirname(__FILE__) + '/../fixtures/alternate_helpers'
@controller_class.helpers_path = [File.dirname(__FILE__) + '/../fixtures/alternate_helpers']
# Reload helpers
@controller_class._helpers = Module.new

View File

@ -1,3 +1,5 @@
module Fun::GamesHelper
def stratego() "Iz guuut!" end
module Fun
module GamesHelper
def stratego() "Iz guuut!" end
end
end

View File

@ -1,3 +1,5 @@
module Fun::PdfHelper
def foobar() 'baz' end
module Fun
module PdfHelper
def foobar() 'baz' end
end
end

View File

@ -8,7 +8,7 @@ require "rails"
module ActiveRecord
class Railtie < Rails::Railtie
plugin_name :active_record
railtie_name :active_record
rake_tasks do
load "active_record/railties/databases.rake"
@ -18,6 +18,11 @@ module ActiveRecord
require "active_record/railties/subscriber"
subscriber ActiveRecord::Railties::Subscriber.new
initializer "active_record.initialize_timezone" do
ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.default_timezone = :utc
end
initializer "active_record.set_configs" do |app|
app.config.active_record.each do |k,v|
ActiveRecord::Base.send "#{k}=", v
@ -31,11 +36,6 @@ module ActiveRecord
ActiveRecord::Base.establish_connection
end
initializer "active_record.initialize_timezone" do
ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.default_timezone = :utc
end
# Expose database runtime to controller for logging.
initializer "active_record.log_runtime" do |app|
require "active_record/railties/controller_runtime"

View File

@ -3,9 +3,15 @@ require "rails"
module ActiveResource
class Railtie < Rails::Railtie
plugin_name :active_resource
railtie_name :active_resource
require "active_resource/railties/subscriber"
subscriber ActiveResource::Railties::Subscriber.new
initializer "active_resource.set_configs" do |app|
app.config.active_resource.each do |k,v|
ActiveResource::Base.send "#{k}=", v
end
end
end
end

View File

@ -0,0 +1,60 @@
require "active_support"
require "rails"
module I18n
class Railtie < Rails::Railtie
railtie_name :i18n
# Initialize I18n load paths to an array
config.i18n.load_path = []
initializer :initialize_i18n do
require 'active_support/i18n'
ActionDispatch::Callbacks.to_prepare do
I18n.reload!
end
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.
config.after_initialize do |app|
app.config.i18n.each do |setting, value|
if setting == :load_path
I18n.load_path += value
else
I18n.send("#{setting}=", value)
end
end
I18n.reload!
end
end
end
module ActiveSupport
class Railtie < Rails::Railtie
railtie_name :active_support
# 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 |app|
require 'active_support/whiny_nil' if app.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 |app|
require 'active_support/core_ext/time/zones'
zone_default = Time.__send__(:get_zone, app.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
end
end

View File

@ -7,4 +7,4 @@ require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
<%= app_const %>.load_tasks
Rails::Application.load_tasks

View File

@ -19,7 +19,7 @@ require 'rails/all'
# To pick the frameworks you want, remove 'require "rails/all"'
# and list the framework railties that you want:
#
# require "active_model/railtie"
# require "active_support/railtie"
# require "active_record/railtie"
# require "action_controller/railtie"
# require "action_view/railtie"
@ -28,7 +28,7 @@ require 'rails/all'
<% else -%>
# Pick the frameworks you want:
# require "active_record/railtie"
require "active_model/railtie"
require "active_support/railtie"
require "action_controller/railtie"
require "action_view/railtie"
require "action_mailer/railtie"

View File

@ -2,4 +2,4 @@ require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands/console'
require File.expand_path('../../config/application', __FILE__)
Rails::Console.start(<%= app_const %>)
Rails::Console.start(Rails::Application)

View File

@ -2,4 +2,4 @@ require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands/dbconsole'
require File.expand_path('../../config/application', __FILE__)
Rails::DBConsole.start(<%= app_const %>)
Rails::DBConsole.start(Rails::Application)

View File

@ -1,5 +1,5 @@
# Allow the metal piece to run in isolation
require File.expand_path('../../../config/environment', __FILE__)
require File.expand_path('../../../config/environment', __FILE__) unless defined?(Rails)
class <%= class_name %>
def self.call(env)

View File

@ -17,7 +17,7 @@ module Rails
def create_tasks_files
return unless options[:tasks]
directory 'tasks', plugin_dir('tasks')
directory 'lib/tasks', plugin_dir('lib/tasks')
end
hook_for :generator do |generator|

View File

@ -4,15 +4,8 @@ require 'active_support'
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/railties_path'
require 'rails/version'
require 'rails/rack'
require 'rails/paths'
require 'rails/configuration'
require 'rails/deprecation'
require 'rails/subscriber'
require 'rails/ruby_version_check'
@ -32,8 +25,6 @@ else
end
module Rails
autoload :Bootstrap, 'rails/bootstrap'
class << self
def application
@@application ||= nil

View File

@ -1,6 +1,7 @@
require "rails"
%w(
active_support
active_model
active_record
action_controller

View File

@ -1,43 +1,64 @@
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 require_environment!
environment = config.paths.config.environment.to_a.first
require environment if environment
end
def initialize
require_environment
Rails.application ||= self
@route_configuration_files = []
def config
@config ||= Application::Configuration.new(self.class.find_root_with_flag("config.ru", Dir.pwd))
end
def routes
::ActionController::Routing::Routes
end
def railties
@railties ||= Railties.new(config)
end
def routes_reloader
@routes_reloader ||= RoutesReloader.new(config)
end
def reload_routes!
routes_reloader.reload!
end
def initialize!
@ -45,74 +66,22 @@ module Rails
self
end
def require_environment
require config.environment_path
rescue LoadError
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
routes_changed_at
end
def reload_routes!
routes.disable_clear_and_finalize = true
routes.clear!
route_configuration_files.each { |config| load(config) }
routes.finalize!
nil
ensure
routes.disable_clear_and_finalize = false
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)
def initializers
initializers = Bootstrap.initializers
initializers += super
railties.all { |r| initializers += r.initializers }
initializers += Finisher.initializers
initializers
end
protected
def initialize_tasks
require "rails/tasks"
task :environment do
$rails_rake_task = true
initialize!
end
end
initializer :build_middleware_stack do
app
def initialize_generators
require "rails/generators"
end
# Fires the user-supplied after_initialize block (Configuration#after_initialize)
initializer :after_initialize 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
ActiveSupport::Dependencies.unhook!
end
# Application is always reloadable when config.cache_classes is false.
def reloadable?(app)
true
end
end
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,294 +1,82 @@
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]
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
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
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
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
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
end
end
def cache_store
@cache_store ||= begin
if File.exist?("#{root}/tmp/cache/")
[ :file_store, "#{root}/tmp/cache/" ]
# 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
:memory_store
@@generators
end
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 after_initialize_blocks
@@after_initialize_blocks ||= []
end
end
def builtin_directories
# Include builtins only in the development environment.
Rails.env.development? ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
end
def after_initialize(&blk)
after_initialize_blocks << blk if blk
end
def log_path
@log_path ||= File.join(root, 'log', "#{Rails.env}.log")
end
def respond_to?(name)
super || name.to_s =~ config_key_regexp
end
def log_level
@log_level ||= Rails.env.production? ? :info : :debug
end
private
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!
def method_missing(name, *args, &blk)
if name.to_s =~ config_key_regexp
return $2 == '=' ? options[$1] = args.first : options[$1]
end
i18n
super
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 config_key_regexp
bits = config_keys.map { |n| Regexp.escape(n.to_s) }.join('|')
/^(#{bits})(?:=)?$/
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
def config_keys
(Railtie.railtie_names + Engine.engine_names).map { |n| n.to_s }.uniq
end
def options
@@options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }
end
end
class Generators #:nodoc:
@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_paths
Dir["#{path}/{lib}", "#{path}/app/{models,controllers,helpers}"]
end
def load_tasks
Dir["#{path}/{tasks,lib/tasks,rails/tasks}/**/*.rake"].sort.each { |ext| load ext }
end
super
extra_tasks = Dir["#{root}/{tasks,rails/tasks}/**/*.rake"]
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
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
initializer :load_init_rb, :before => :load_application_initializers do |app|
file = "#{@path}/init.rb"
def initialize(root)
@name = File.basename(root).to_sym
config.root = root
end
def config
@config ||= Engine::Configuration.new
end
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)
eval(File.read(file), binding, file) if file && 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
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

View File

@ -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
@metals = load_list.map { |metal|
metal = File.basename(metal, '.rb')
require_dependency metal
metal.camelize.constantize
}.compact
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 = metals.map { |m| m.to_s.camelize.constantize }
end
def new(app)

View File

@ -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 self.generators(&blk)
@generators ||= []
@generators << blk if blk
@generators
def generators(&blk)
@generators ||= []
@generators << blk if blk
@generators
end
protected
def abstract_railtie?(base)
ABSTRACT_RAILTIES.include?(base.name)
end
# 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

View File

@ -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

View File

@ -0,0 +1,9 @@
require 'rails/configuration'
module Rails
class Railtie
class Configuration
include Rails::Configuration::Shared
end
end
end

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -9,8 +9,8 @@ class ConsoleTest < Test::Unit::TestCase
# Load steps taken from rails/commands/console.rb
require "#{rails_root}/config/environment"
require 'rails/console_app'
require 'rails/console_with_helpers'
require 'rails/console/app'
require 'rails/console/helpers'
end
def test_app_method_should_return_integration_session

View File

@ -29,7 +29,7 @@ module ApplicationTests
add_to_config <<-RUBY
config.root = "#{app_path}"
config.eager_load_paths = "#{app_path}/lib"
config.eager_load_paths << "#{app_path}/lib"
RUBY
require "#{app_path}/config/environment"
@ -38,13 +38,24 @@ module ApplicationTests
end
test "load environment with global" do
app_file "config/environments/development.rb", "$initialize_test_set_from_env = 'success'"
app_file "config/environments/development.rb", <<-RUBY
$initialize_test_set_from_env = 'success'
AppTemplate::Application.configure do
config.cache_classes = true
config.time_zone = "Brasilia"
end
RUBY
assert_nil $initialize_test_set_from_env
add_to_config <<-RUBY
config.root = "#{app_path}"
config.time_zone = "UTC"
RUBY
require "#{app_path}/config/environment"
assert_equal "success", $initialize_test_set_from_env
assert AppTemplate::Application.config.cache_classes
assert_equal "Brasilia", AppTemplate::Application.config.time_zone
end
test "action_controller load paths set only if action controller in use" do

View File

@ -1,17 +1,6 @@
require "isolation/abstract_unit"
module ApplicationTests
class MyQueue
def publish(name, *args)
raise name
end
# Not a full queue implementation
def method_missing(name, *args, &blk)
self
end
end
class MockLogger
def method_missing(*args)
@logged ||= []
@ -39,22 +28,6 @@ module ApplicationTests
ActiveSupport::Notifications.notifier.wait
end
test "new queue is set" do
# We don't want to load all frameworks, so remove them and clean up environments.
use_frameworks []
FileUtils.rm_rf("#{app_path}/config/environments")
add_to_config <<-RUBY
config.notifications.notifier = ActiveSupport::Notifications::Notifier.new(ApplicationTests::MyQueue.new)
RUBY
require "#{app_path}/config/environment"
assert_raise RuntimeError do
ActiveSupport::Notifications.publish('foo')
end
end
test "rails subscribers are added" do
add_to_config <<-RUBY
config.colorize_logging = false

View File

@ -48,7 +48,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_creates_tasks_if_required
run_generator ["plugin_fu", "--tasks"]
assert_file "vendor/plugins/plugin_fu/tasks/plugin_fu_tasks.rake"
assert_file "vendor/plugins/plugin_fu/lib/tasks/plugin_fu_tasks.rake"
end
def test_creates_generator_if_required

View File

@ -10,14 +10,14 @@ module InitializableTests
attr_accessor :foo, :bar
end
initializer :omg, :global => true do
initializer :omg do
@foo ||= 0
@foo += 1
end
end
class Bar < Foo
initializer :bar, :global => true do
initializer :bar do
@bar ||= 0
@bar += 1
end
@ -26,7 +26,7 @@ module InitializableTests
module Word
include Rails::Initializable
initializer :word, :global => true do
initializer :word do
$word = "bird"
end
end
@ -34,11 +34,11 @@ module InitializableTests
class Parent
include Rails::Initializable
initializer :one, :global => true do
initializer :one do
$arr << 1
end
initializer :two, :global => true do
initializer :two do
$arr << 2
end
end
@ -46,17 +46,17 @@ module InitializableTests
class Child < Parent
include Rails::Initializable
initializer :three, :before => :one, :global => true do
initializer :three, :before => :one do
$arr << 3
end
initializer :four, :after => :one, :global => true do
initializer :four, :after => :one do
$arr << 4
end
end
class Parent
initializer :five, :before => :one, :global => true do
initializer :five, :before => :one do
$arr << 5
end
end
@ -72,11 +72,11 @@ module InitializableTests
$arr << 2
end
initializer :three, :global => true do
initializer :three do
$arr << 3
end
initializer :four, :global => true do
initializer :four do
$arr << 4
end
end
@ -181,13 +181,7 @@ module InitializableTests
$arr = []
instance = Instance.new
instance.run_initializers
assert_equal [1, 2], $arr
end
test "running globals" do
$arr = []
Instance.run_initializers
assert_equal [3, 4], $arr
assert_equal [1, 2, 3, 4], $arr
end
end

View File

@ -1,55 +0,0 @@
require "isolation/abstract_unit"
module InitializerTests
class InitializeI18nTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation
def setup
build_app
boot_rails
end
# test_config_defaults_and_settings_should_be_added_to_i18n_defaults
test "i18n config defaults and settings should be added to i18n defaults" do
add_to_config <<-RUBY
config.root = "#{app_path}"
config.i18n.load_path << "my/other/locale.yml"
RUBY
require "#{app_path}/config/environment"
#{RAILS_FRAMEWORK_ROOT}/railties/test/fixtures/plugins/engines/engine/config/locales/en.yml
assert_equal %W(
#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/railties/tmp/app/config/locales/en.yml
my/other/locale.yml
).map { |path| File.expand_path(path) }, I18n.load_path.map { |path| File.expand_path(path) }
end
test "i18n finds locale files in engines" do
# app_file "vendor/plugins/engine/init.rb", ""
# app_file "vendor/plugins/engine/app/models/hellos.rb", "class Hello ; end"
# app_file "vendor/plugins/engine/lib/omg.rb", "puts 'omg'"
# app_file "vendor/plugins/engine/config/locales/en.yml", "hello:"
#
# Rails::Initializer.run do |c|
# c.root = app_path
# c.i18n.load_path << "my/other/locale.yml"
# end
# Rails.initialize!
#
# #{RAILS_FRAMEWORK_ROOT}/railties/test/fixtures/plugins/engines/engine/config/locales/en.yml
# assert_equal %W(
# #{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
# #{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
# #{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
# #{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml
# #{app_path}/config/locales/en.yml
# my/other/locale.yml
# #{app_path}/vendor/plugins/engine/config/locales/en.yml
# ).map { |path| File.expand_path(path) }, I18n.load_path.map { |path| File.expand_path(path) }
end
end
end

View File

@ -8,6 +8,7 @@ module InitializerTests
build_app
boot_rails
FileUtils.rm_rf("#{app_path}/config/environments")
app_file "config/environments/development.rb", ""
add_to_config <<-RUBY
config.root = "#{app_path}"
config.after_initialize do
@ -36,19 +37,17 @@ module InitializerTests
end
test "booting up Rails yields a valid paths object" do
assert_path @paths.app, "app"
assert_path @paths.app.metals, "app", "metal"
assert_path @paths.app.models, "app", "models"
assert_path @paths.app.helpers, "app", "helpers"
assert_path @paths.app.services, "app", "services"
assert_path @paths.app.views, "app", "views"
assert_path @paths.lib, "lib"
assert_path @paths.vendor, "vendor"
assert_path @paths.vendor.plugins, "vendor", "plugins"
assert_path @paths.tmp, "tmp"
assert_path @paths.tmp.cache, "tmp", "cache"
assert_path @paths.config, "config"
assert_path @paths.config.locales, "config", "locales"
assert_path @paths.config.environments, "config", "environments"
assert_path @paths.config.locales, "config", "locales", "en.yml"
assert_path @paths.config.environment, "config", "environments", "development.rb"
assert_equal root("app", "controllers"), @paths.app.controllers.to_a.first
assert_equal Pathname.new(File.dirname(__FILE__)).join("..", "..", "builtin", "rails_info").expand_path,
@ -56,27 +55,23 @@ module InitializerTests
end
test "booting up Rails yields a list of paths that are eager" do
assert @paths.app.models.eager_load?
assert @paths.app.eager_load?
assert @paths.app.controllers.eager_load?
assert @paths.app.helpers.eager_load?
assert @paths.app.metals.eager_load?
end
test "environments has a glob equal to the current environment" do
assert_equal "#{Rails.env}.rb", @paths.config.environments.glob
assert_equal "#{Rails.env}.rb", @paths.config.environment.glob
end
test "load path includes each of the paths in config.paths as long as the directories exist" do
assert_in_load_path "app"
assert_in_load_path "app", "controllers"
assert_in_load_path "app", "models"
assert_in_load_path "app", "helpers"
assert_in_load_path "lib"
assert_in_load_path "vendor"
assert_not_in_load_path "app", "views"
assert_not_in_load_path "app", "metal"
assert_not_in_load_path "app", "services"
assert_not_in_load_path "config"
assert_not_in_load_path "config", "locales"
assert_not_in_load_path "config", "environments"
@ -86,17 +81,17 @@ module InitializerTests
test "controller paths include builtin in development mode" do
Rails.env.replace "development"
assert Rails::Configuration.new.paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
assert Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
end
test "controller paths does not have builtin_directories in test mode" do
Rails.env.replace "test"
assert !Rails::Configuration.new.paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
assert !Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
end
test "controller paths does not have builtin_directories in production mode" do
Rails.env.replace "production"
assert !Rails::Configuration.new.paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
assert !Rails::Application::Configuration.new("/").paths.app.controllers.paths.any? { |p| p =~ /builtin/ }
end
end

View File

@ -3,22 +3,23 @@ require 'rails/paths'
class PathsTest < ActiveSupport::TestCase
def setup
@root = Rails::Application::Root.new("/foo/bar")
File.stubs(:exists?).returns(true)
@root = Rails::Paths::Root.new("/foo/bar")
end
test "the paths object is initialized with the root path" do
root = Rails::Application::Root.new("/fiz/baz")
root = Rails::Paths::Root.new("/fiz/baz")
assert_equal "/fiz/baz", root.path
end
test "the paths object can be initialized with nil" do
assert_nothing_raised do
Rails::Application::Root.new(nil)
Rails::Paths::Root.new(nil)
end
end
test "a paths object initialized with nil can be updated" do
root = Rails::Application::Root.new(nil)
root = Rails::Paths::Root.new(nil)
root.app = "app"
root.path = "/root"
assert_equal ["/root/app"], root.app.to_a
@ -30,7 +31,7 @@ class PathsTest < ActiveSupport::TestCase
end
test "raises exception if root path never set" do
root = Rails::Application::Root.new(nil)
root = Rails::Paths::Root.new(nil)
root.app = "app"
assert_raises RuntimeError do
root.app.to_a
@ -110,7 +111,7 @@ class PathsTest < ActiveSupport::TestCase
end
test "the root can only have one physical path" do
assert_raise(RuntimeError) { Rails::Application::Root.new(["/fiz", "/biz"]) }
assert_raise(RuntimeError) { Rails::Paths::Root.new(["/fiz", "/biz"]) }
assert_raise(RuntimeError) { @root.push "/biz" }
assert_raise(RuntimeError) { @root.unshift "/biz" }
assert_raise(RuntimeError) { @root.concat ["/biz"]}
@ -193,12 +194,7 @@ class PathsTest < ActiveSupport::TestCase
assert_equal 2, @root.eager_load.size
end
test "a path should have a glob that defaults to **/*.rb" do
@root.app = "/app"
assert_equal "**/*.rb", @root.app.glob
end
test "it should be possible to override a path's default glob" do
test "it should be possible to add a path's default glob" do
@root.app = "/app"
@root.app.glob = "*.rb"
assert_equal "*.rb", @root.app.glob
@ -227,4 +223,11 @@ class PathsTest < ActiveSupport::TestCase
@root.app.eager_load!
assert_equal ["/foo/bar/app"], @root.load_paths
end
test "adding a path to the load once paths also adds it to the load path" do
@root.app = "app"
@root.app.load_once!
assert_equal ["/foo/bar/app"], @root.load_paths
end
end

View File

@ -26,11 +26,11 @@ module PluginsTest
test "plugin config merges are deep" do
class Foo < Rails::Railtie ; config.foo.greetings = 'hello' ; end
class MyApp < Rails::Application
class Bar < Rails::Railtie
config.foo.bar = "bar"
end
assert_equal "hello", MyApp.config.foo.greetings
assert_equal "bar", MyApp.config.foo.bar
assert_equal "hello", Bar.config.foo.greetings
assert_equal "bar", Bar.config.foo.bar
end
test "plugin can add subscribers" do

View File

@ -17,6 +17,10 @@ module PluginsTest
require "#{app_path}/config/environment"
end
def app
@app ||= Rails.application
end
test "it loads the plugin's init.rb file" do
boot_rails
assert_equal "loaded", BUKKITS
@ -145,6 +149,156 @@ module PluginsTest
response = Rails.application.call(Rack::MockRequest.env_for("/sprokkit"))
assert_equal "I am a Sprokkit", response[2].join
end
test "tasks are loaded by default" do
$executed = false
@plugin.write "lib/tasks/foo.rake", <<-RUBY
task :foo do
$executed = true
end
RUBY
boot_rails
require 'rake'
require 'rake/rdoctask'
require 'rake/testtask'
Rails.application.load_tasks
Rake::Task[:foo].invoke
assert $executed
end
test "deprecated tasks are also loaded" do
$executed = false
@plugin.write "tasks/foo.rake", <<-RUBY
task :foo do
$executed = true
end
RUBY
boot_rails
require 'rake'
require 'rake/rdoctask'
require 'rake/testtask'
Rails.application.load_tasks
Rake::Task[:foo].invoke
assert $executed
end
test "i18n files are added with lower priority than application ones" do
add_to_config <<-RUBY
config.i18n.load_path << "#{app_path}/app/locales/en.yml"
RUBY
app_file 'app/locales/en.yml', <<-YAML
en:
bar: "1"
YAML
app_file 'config/locales/en.yml', <<-YAML
en:
foo: "2"
bar: "2"
YAML
@plugin.write 'config/locales/en.yml', <<-YAML
en:
foo: "3"
YAML
boot_rails
assert_equal %W(
#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml
#{app_path}/vendor/plugins/bukkits/config/locales/en.yml
#{app_path}/config/locales/en.yml
#{app_path}/app/locales/en.yml
).map { |path| File.expand_path(path) }, I18n.load_path.map { |path| File.expand_path(path) }
assert_equal "2", I18n.t(:foo)
assert_equal "1", I18n.t(:bar)
end
test "plugin metals are added to the middleware stack" do
@plugin.write 'app/metal/foo_metal.rb', <<-RUBY
class FooMetal
def self.call(env)
[200, { "Content-Type" => "text/html"}, ["FooMetal"]]
end
end
RUBY
boot_rails
require 'rack/test'
extend Rack::Test::Methods
get "/"
assert_equal 200, last_response.status
assert_equal "FooMetal", last_response.body
end
test "namespaced controllers with namespaced routes" do
@plugin.write "config/routes.rb", <<-RUBY
ActionController::Routing::Routes.draw do
namespace :admin do
match "index", :to => "admin/foo#index"
end
end
RUBY
@plugin.write "app/controllers/admin/foo_controller.rb", <<-RUBY
class Admin::FooController < ApplicationController
def index
render :text => "Rendered from namespace"
end
end
RUBY
boot_rails
require 'rack/test'
extend Rack::Test::Methods
get "/admin/index"
assert_equal 200, last_response.status
assert_equal "Rendered from namespace", last_response.body
end
test "plugin with initializers" do
$plugin_initializer = false
@plugin.write "config/initializers/foo.rb", <<-RUBY
$plugin_initializer = true
RUBY
boot_rails
assert $plugin_initializer
end
test "plugin cannot declare an engine for it" do
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
class Engine < Rails::Engine
end
end
RUBY
@plugin.write "init.rb", <<-RUBY
require "bukkits"
RUBY
rescued = false
begin
boot_rails
rescue Exception => e
rescued = true
assert_equal '"bukkits" is a Railtie/Engine and cannot be installed as plugin', e.message
end
assert rescued, "Expected boot rails to fail"
end
end
class VendoredOrderingTest < Test::Unit::TestCase