aboutsummaryrefslogblamecommitdiffstats
path: root/railties/lib/rails/configuration.rb
blob: 5d0c7fd4b483c0671c67b07cb416c099e0944b19 (plain) (tree)
1
2
3
                                        
 
            





















































                                                                                                                                                  


         


























                                                           


       

                                                                               
                              

                                 



                      



                                             



                                         
                                                                 
         








                                                                    
                                                  



                                                      

                                                                







                        
                                                   


                                                                                      


                                                                       
                                                                                   

                                                                              




                                                    



                                                          









                                            


       
                                             




                                                                    
 
                           
           


                                 
       
 

                      
                     
                                                                         



                                                       
                                                             



                                                                                                     
                                                                    
                                                                                

           

             

       
                         

                                                                             



                                







                                                                                
                                                                                   


          




                                                                             


                                                                           






















                                                                                 















                                                                                            

       
                                 




















                                                                                              

       



                                                                          

       










                                                                                   
     
   
require 'active_support/ordered_options'

module Rails
  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

    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

  # 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

    def respond_to?(name)
      super || name.to_s =~ config_key_regexp
    end

  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
      Railtie.plugin_names.map { |n| n.to_s }.uniq
    end
  end

  class Engine::Configuration < Railtie::Configuration
    attr_reader :root
    attr_writer :eager_load_paths, :load_once_paths, :load_paths

    def initialize(root)
      @root = root
      super()
    end

    def paths
      @paths ||= begin
        paths = Rails::Application::Root.new(@root)
        paths.app                 "app",             :eager_load => true, :glob => "*"
        paths.app.controllers     "app/controllers", :eager_load => true
        paths.app.metals          "app/metal",       :eager_load => true
        paths.app.views           "app/views"
        paths.lib                 "lib",             :load_path => true
        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

  class Configuration < Engine::Configuration
    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

    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

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

    # Deprecated paths
    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