diff options
| author | José Valim <jose.valim@gmail.com> | 2010-01-23 01:29:29 +0100 | 
|---|---|---|
| committer | José Valim <jose.valim@gmail.com> | 2010-01-23 01:29:29 +0100 | 
| commit | 98240c49b05093d6d14b9384a9bd695b58eefb59 (patch) | |
| tree | 8db75608481547569fe86b105d7af30017617d69 /railties/lib/rails | |
| parent | c8cc8a987213bf90fe6922517d52befb7c0587a8 (diff) | |
| download | rails-98240c49b05093d6d14b9384a9bd695b58eefb59.tar.gz rails-98240c49b05093d6d14b9384a9bd695b58eefb59.tar.bz2 rails-98240c49b05093d6d14b9384a9bd695b58eefb59.zip  | |
Get rid of initializers global and create i18n railtie.
Diffstat (limited to 'railties/lib/rails')
| -rw-r--r-- | railties/lib/rails/application.rb | 76 | ||||
| -rw-r--r-- | railties/lib/rails/bootstrap.rb | 51 | ||||
| -rw-r--r-- | railties/lib/rails/configuration.rb | 285 | ||||
| -rw-r--r-- | railties/lib/rails/engine.rb | 48 | ||||
| -rw-r--r-- | railties/lib/rails/initializable.rb | 19 | 
5 files changed, 206 insertions, 273 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 5c4112e1d7..9b0f39feb1 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -2,6 +2,11 @@ require 'fileutils'  module Rails    class Application < Engine +   +    # TODO Clear up 2 way delegation flow between App class and instance. +    # Infact just add a method_missing on the class. +    # +    # TODO I'd like to track the "default app" different using an inherited hook.      class << self        alias    :configure :class_eval        delegate :initialize!, :load_tasks, :load_generators, :root, :to => :instance @@ -70,10 +75,9 @@ module Rails        routes.disable_clear_and_finalize = false      end -      def require_environment -      require config.environment_path -    rescue LoadError +      environment = config.paths.config.environment.to_a.first +      require environment if environment      end      def load_tasks @@ -92,13 +96,6 @@ module Rails        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 @@ -120,59 +117,30 @@ module Rails        app.call(env)      end -    initializer :add_builtin_route, :before => :build_middleware_stack do |app| +    def initializers +      my = super +      hook = my.index { |i| i.name == :set_autoload_paths } + 1 +      initializers = Bootstrap.new(self).initializers +      initializers += my[0...hook] +      plugins.each { |p| initializers += p.initializers } +      initializers += my[hook..-1] +      initializers +    end + +    initializer :add_builtin_route do |app|        if Rails.env.development?          app.route_configuration_files << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')        end      end -    initializer :build_middleware_stack, :after => :load_application_initializers do +    initializer :build_middleware_stack do        app      end -    # Fires the user-supplied after_initialize block (Configuration#after_initialize) -    initializer :after_initialize, :after => :build_middleware_stack do +    # Fires the user-supplied after_initialize block (config#after_initialize) +    initializer :after_initialize do        config.after_initialize_blocks.each do |block| -        block.call -      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. -    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) +        block.call(self)        end      end diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb index 3473f2fcaa..7c33955b2b 100644 --- a/railties/lib/rails/bootstrap.rb +++ b/railties/lib/rails/bootstrap.rb @@ -1,5 +1,5 @@  module Rails -  class Bootstrap #< Railtie +  class Bootstrap      include Initializable      def initialize(application) @@ -12,6 +12,15 @@ module Rails        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          logger = ActiveSupport::BufferedLogger.new(config.paths.log.to_a.first) @@ -29,32 +38,42 @@ module Rails        end      end -    initializer :container do -      # FIXME This is just a dumb initializer used as hook -    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 - +    # 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) -          # Insert middleware to setup and teardown local cache for each request            config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)          end        end      end -    # Sets the dependency loading mechanism based on the value of -    # Configuration#cache_classes. +    # 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 +      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 -      # TODO: Remove files from the $" and always use require        ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load      end    end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index 3ba27d79a7..76ca52867b 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -1,59 +1,112 @@  require 'active_support/ordered_options'  module Rails -  module SharedConfiguration -    def self.middleware_stack -      @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') +  module Shared +    # Those configuration values are shared between railtie, engines and so forth. +    module Configuration +      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.paths.app.metals.to_a, Rails.application.config.metals) }) +          middleware.use('ActionDispatch::ParamsParser') +          middleware.use('::Rack::MethodOverride') +          middleware.use('::ActionDispatch::Head') +        end +      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 ||= GeneratorsConfiguration.new +        if block_given? +          yield @@generators +        else +          @@generators +        end +      end + +      def after_initialize_blocks +        @@after_initialize_blocks ||= [] +      end + +      def after_initialize(&blk) +        after_initialize_blocks << blk if blk +      end + +    protected + +      def options +        @@options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new }        end      end -    def self.options -      @options ||= Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new } +    class GeneratorsConfiguration #:nodoc: +      attr_accessor :aliases, :options, :colorize_logging + +      def initialize +        @aliases = Hash.new { |h,k| h[k] = {} } +        @options = Hash.new { |h,k| h[k] = {} } +        @colorize_logging = true +      end + +      def method_missing(method, *args) +        method = method.to_s.sub(/=$/, '').to_sym + +        if method == :rails +          namespace, configuration = :rails, args.shift +        elsif args.first.is_a?(Hash) +          namespace, configuration = method, args.shift +        else +          namespace, configuration = args.shift, args.shift +          @options[:rails][method] = namespace +        end + +        if configuration +          aliases = configuration.delete(:aliases) +          @aliases[namespace].merge!(aliases) if aliases +          @options[namespace].merge!(configuration) +        end +      end      end    end -  # Temporarily separate the plugin configuration class from the main -  # configuration class while this bit is being cleaned up. +  # Holds Railtie basic configuration. It does not include configuration values +  # related with load paths and the application specifics.    class Railtie::Configuration +    include Shared::Configuration +      def self.default        @default ||= new      end -    attr_reader :middleware - -    def initialize -      @options    = SharedConfiguration.options -      @middleware = SharedConfiguration.middleware_stack -    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] +        return $2 == '=' ? options[$1] = args.first : options[$1]        end -        super      end @@ -68,8 +121,8 @@ module Rails    end    class Engine::Configuration < Railtie::Configuration -    attr_reader   :root -    attr_accessor :eager_load_paths, :load_once_paths, :load_paths +    attr_reader :root +    attr_writer :eager_load_paths, :load_once_paths, :load_paths      def initialize(root)        @root = root @@ -86,8 +139,8 @@ module Rails          paths.lib                 "lib",             :load_path => true          paths.config              "config"          paths.config.environment  "config/environments", :glob => "#{Rails.env}.rb" -        paths.config.initializers "config/initializers" -        paths.config.locales      "config/locales" +        paths.config.initializers "config/initializers", :glob => "**/*.rb" +        paths.config.locales      "config/locales",      :glob => "*.{rb,yml}"          paths.config.routes       "config/routes.rb"          paths        end @@ -111,41 +164,35 @@ module Rails    end    class Configuration < Engine::Configuration -    attr_accessor :after_initialize_blocks, :cache_classes, :colorize_logging, -                  :consider_all_requests_local, :dependency_loading, :filter_parameters, -                  :logger, :metals, :plugins, -                  :preload_frameworks, :reload_plugins, :serve_static_assets, -                  :time_zone, :whiny_nils +    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 -    attr_writer :cache_store, :controller_paths, :i18n, :log_level -    def initialize(*) +    def initialize(*)              super -      @after_initialize_blocks      = [] -      @filter_parameters            = [] -      @dependency_loading           = true -      @serve_static_assets          = true -    end - -    def after_initialize(&blk) -      @after_initialize_blocks << blk if blk -    end +      @filter_parameters   = [] +      @dependency_loading  = true +      @serve_static_assets = true +    end                          def paths        @paths ||= begin          paths = super -        paths.app.controllers.concat(builtin_directories) +        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             "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/#{Rails.env}", :load_path => true +          paths.mocks_path  "test/mocks", :load_path => true, :glob => Rails.env          end          paths @@ -182,6 +229,29 @@ module Rails        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 + +    # Deprecated paths      def view_path=(value)        ActiveSupport::Deprecation.warn "config.view_path= is deprecated, " <<          "please do config.paths.app.views= instead", caller @@ -241,108 +311,5 @@ module Rails          "please do config.paths.app.controllers instead", caller        paths.app.controllers.to_a.uniq      end - -    def cache_store -      @cache_store ||= begin -        if File.exist?("#{root}/tmp/cache/") -          [ :file_store, "#{root}/tmp/cache/" ] -        else -          :memory_store -        end -      end -    end - -    # Include builtins only in the development environment. -    def builtin_directories -      Rails.env.development? ? Dir["#{RAILTIES_PATH}/builtin/*/"] : [] -    end - -    def log_level -      @log_level ||= Rails.env.production? ? :info : :debug -    end - -    def time_zone -      @time_zone ||= "UTC" -    end - -    def i18n -      @i18n ||= begin -        i18n = ActiveSupport::OrderedOptions.new -        i18n.load_path = [] - -        if File.exist?(File.join(root, 'config', 'locales')) -          i18n.load_path << Dir[File.join(root, 'config', 'locales', '*.{rb,yml}')] -          i18n.load_path.flatten! -        end - -        i18n -      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 -      end -    end - -    # Allow Notifications queue to be modified or add subscriptions: -    # -    #   config.notifications.queue = MyNewQueue.new -    # -    #   config.notifications.subscribe /action_dispatch.show_exception/ do |*args| -    #     ExceptionDeliver.deliver_exception(args) -    #   end -    # -    def notifications -      ActiveSupport::Notifications -    end - -    class Generators #:nodoc: -      attr_accessor :aliases, :options, :colorize_logging - -      def initialize -        @aliases = Hash.new { |h,k| h[k] = {} } -        @options = Hash.new { |h,k| h[k] = {} } -        @colorize_logging = true -      end - -      def method_missing(method, *args) -        method = method.to_s.sub(/=$/, '').to_sym - -        if method == :rails -          namespace, configuration = :rails, args.shift -        elsif args.first.is_a?(Hash) -          namespace, configuration = method, args.shift -        else -          namespace, configuration = args.shift, args.shift -          @options[:rails][method] = namespace -        end - -        if configuration -          aliases = configuration.delete(:aliases) -          @aliases[namespace].merge!(aliases) if aliases -          @options[namespace].merge!(configuration) -        end -      end -    end    end  end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index effbfee6c1..93f39f176c 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -4,7 +4,6 @@ module Rails    # TODO Move I18n here    # TODO Set routes namespaces    class Engine < Railtie -      class << self        attr_accessor :called_from @@ -49,8 +48,8 @@ module Rails      delegate :middleware, :root, :to => :config      # Add configured load paths to ruby load paths and remove duplicates. -    initializer :set_load_path, :before => :container do -      expand_load_path(config.load_paths).reverse_each do |path| +    initializer :set_load_path do +      config.load_paths.reverse_each do |path|          $LOAD_PATH.unshift(path) if File.directory?(path)        end        $LOAD_PATH.uniq! @@ -58,11 +57,9 @@ module Rails      # Set the paths from which Rails will automatically load source files,      # and the load_once paths. -    initializer :set_autoload_paths, :before => :container 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) +    initializer :set_autoload_paths do +      ActiveSupport::Dependencies.load_paths.concat(config.load_paths) +      ActiveSupport::Dependencies.load_once_paths.concat(config.load_once_paths)        extra = ActiveSupport::Dependencies.load_once_paths -                ActiveSupport::Dependencies.load_paths @@ -74,31 +71,32 @@ module Rails          end_error        end -      # Freeze the arrays so future modifications will fail rather than do nothing mysteriously +      # Freeze so future modifications will fail rather than do nothing mysteriously        config.load_once_paths.freeze      end -    # Routing must be initialized after plugins to allow the former to extend the routes      initializer :add_routing_files do |app| -      routes = select_existing(config.paths.config.routes) -      app.route_configuration_files.concat(routes) +      config.paths.config.routes.to_a.each do |route| +        app.route_configuration_files << route if File.exists?(route) +      end +    end + +    initializer :add_locales do +      config.i18n.load_path.concat(config.paths.config.locales.to_a)      end      initializer :add_view_paths do -      views = select_existing(config.paths.app.views) -      ActionController::Base.view_paths.concat(views) if defined? ActionController -      ActionMailer::Base.view_paths.concat(views)     if defined? ActionMailer +      views = config.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 :load_application_initializers do -      select_existing(config.paths.config.initializers).each do |initializers| -        Dir["#{initializers}/**/*.rb"].sort.each do |initializer| -          load(initializer) -        end +      config.paths.config.initializers.each do |initializer| +        load(initializer)        end      end -    # Eager load application classes      initializer :load_application_classes do |app|        next if $rails_rake_task @@ -111,15 +109,5 @@ module Rails          end        end      end - -  private - -    def select_existing(paths) -      paths.to_a.select { |path| File.exists?(path) }.uniq -    end - -    def expand_load_path(load_paths) -      load_paths.map { |path| Dir.glob(path.to_s) }.flatten.uniq -    end    end  end
\ No newline at end of file diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb index 8fcb254590..cea4a0fdf7 100644 --- a/railties/lib/rails/initializable.rb +++ b/railties/lib/rails/initializable.rb @@ -19,12 +19,6 @@ module Rails          @options[:after]        end -      def global -        @options[:global] -      end - -      alias global? global -        def run(*args)          @context.instance_exec(*args, &block)        end @@ -71,7 +65,7 @@ module Rails      def initializers        @initializers ||= begin -        initializers = self.class.initializers_for(:instance) +        initializers = self.class.initializers_chain          Collection.new(initializers.map { |i| i.bind(self) })        end      end @@ -81,26 +75,23 @@ module Rails          @initializers ||= []        end -      def initializers_for(scope = :global) +      def initializers_chain          initializers = Collection.new          ancestors.reverse_each do |klass|            next unless klass.respond_to?(:initializers) -          initializers = initializers + klass.initializers.select { |i| -            (scope == :global) == !!i.global? -          } +          initializers = initializers + klass.initializers          end          initializers        end        def initializer(name, opts = {}, &blk)          raise ArgumentError, "A block must be passed when defining an initializer" unless blk -        @initializers ||= [] -        @initializers << Initializer.new(name, nil, opts, &blk) +        initializers << Initializer.new(name, nil, opts, &blk)        end        def run_initializers(*args)          return if @ran -        initializers_for(:global).each do |initializer| +        initializers_chain.each do |initializer|            instance_exec(*args, &initializer.block)          end          @ran = true  | 
