configuration.rb 7.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
module Rails
  class Configuration
    attr_accessor :cache_classes, :load_paths, :eager_load_paths, :framework_paths,
                  :load_once_paths, :gems_dependencies_loaded, :after_initialize_blocks,
                  :frameworks, :framework_root_path, :root_path, :plugin_paths, :plugins,
                  :plugin_loader, :plugin_locators, :gems, :loaded_plugins, :reload_plugins,
                  :i18n, :gems, :whiny_nils, :consider_all_requests_local,
                  :action_controller, :active_record, :action_view, :active_support,
                  :action_mailer, :active_resource,
                  :log_path, :log_level, :logger, :preload_frameworks,
                  :database_configuration_file, :cache_store, :time_zone,
                  :view_path, :metals, :controller_paths, :routes_configuration_file,
                  :eager_load_paths, :dependency_loading

    def initialize
      set_root_path!

      @framework_paths              = []
      @load_once_paths              = []
      @after_initialize_blocks      = []
      @loaded_plugins               = []
      @dependency_loading           = true
      @eager_load_paths             = default_eager_load_paths
      @load_paths                   = default_load_paths
      @plugin_paths                 = default_plugin_paths
      @frameworks                   = default_frameworks
      @plugin_loader                = default_plugin_loader
      @plugin_locators              = default_plugin_locators
      @gems                         = default_gems
      @i18n                         = default_i18n
      @log_path                     = default_log_path
      @log_level                    = default_log_level
      @cache_store                  = default_cache_store
      @view_path                    = default_view_path
      @controller_paths             = default_controller_paths
      @routes_configuration_file    = default_routes_configuration_file
      @database_configuration_file  = default_database_configuration_file

      for framework in default_frameworks
        self.send("#{framework}=", Rails::OrderedOptions.new)
      end
      self.active_support = Rails::OrderedOptions.new
    end

    def after_initialize(&blk)
      @after_initialize_blocks << blk if blk
    end

    def set_root_path!
      raise 'RAILS_ROOT is not set' unless defined?(RAILS_ROOT)
      raise 'RAILS_ROOT is not a directory' unless File.directory?(RAILS_ROOT)

      self.root_path =
        # Pathname is incompatible with Windows, but Windows doesn't have
        # real symlinks so File.expand_path is safe.
        if RUBY_PLATFORM =~ /(:?mswin|mingw)/
          File.expand_path(RAILS_ROOT)

        # Otherwise use Pathname#realpath which respects symlinks.
        else
          Pathname.new(RAILS_ROOT).realpath.to_s
        end

      RAILS_ROOT.replace self.root_path
    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
      self
    end

    def framework_paths
      paths = %w(railties railties/lib activesupport/lib)
      paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view)

      [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
        paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework)
      end

      paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
    end

    def framework_root_path
      defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails"
    end

    # TODO: Fix this when there is an application object
    def middleware
      ActionController::Dispatcher.middleware
    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 default_routes_configuration_file
      File.join(root_path, 'config', 'routes.rb')
    end

    def default_controller_paths
      paths = [File.join(root_path, 'app', 'controllers')]
      paths.concat builtin_directories
      paths
    end

    def default_cache_store
      if File.exist?("#{root_path}/tmp/cache/")
        [ :file_store, "#{root_path}/tmp/cache/" ]
      else
        :memory_store
      end
    end

    def default_database_configuration_file
      File.join(root_path, 'config', 'database.yml')
    end

    def default_view_path
      File.join(root_path, 'app', 'views')
    end

    def default_eager_load_paths
      %w(
        app/metal
        app/models
        app/controllers
        app/helpers
      ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
    end

    def default_load_paths
      paths = []

      # Add the old mock paths only if the directories exists
      paths.concat(Dir["#{root_path}/test/mocks/#{RAILS_ENV}"]) if File.exists?("#{root_path}/test/mocks/#{RAILS_ENV}")

      # Add the app's controller directory
      paths.concat(Dir["#{root_path}/app/controllers/"])

      # Followed by the standard includes.
      paths.concat %w(
        app
        app/metal
        app/models
        app/controllers
        app/helpers
        app/services
        lib
        vendor
      ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }

      paths.concat builtin_directories
    end

    def builtin_directories
      # Include builtins only in the development environment.
      (RAILS_ENV == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
    end

    def default_log_path
      File.join(root_path, 'log', "#{RAILS_ENV}.log")
    end

    def default_log_level
      RAILS_ENV == 'production' ? :info : :debug
    end

    def default_frameworks
      [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
    end

    def default_plugin_paths
      ["#{root_path}/vendor/plugins"]
    end

    def default_plugin_loader
      require 'rails/plugin/loader'
      Plugin::Loader
    end

    def default_plugin_locators
      require 'rails/plugin/locator'
      locators = []
      locators << Plugin::GemLocator if defined? Gem
      locators << Plugin::FileSystemLocator
    end

    def default_i18n
      i18n = Rails::OrderedOptions.new
      i18n.load_path = []

      if File.exist?(File.join(RAILS_ROOT, 'config', 'locales'))
        i18n.load_path << Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')]
        i18n.load_path.flatten!
      end

      i18n
    end

    # Adds a single Gem dependency to the rails application. By default, it will require
    # the library with the same name as the gem. Use :lib to specify a different name.
    #
    #   # gem 'aws-s3', '>= 0.4.0'
    #   # require 'aws/s3'
    #   config.gem 'aws-s3', :lib => 'aws/s3', :version => '>= 0.4.0', \
    #     :source => "http://code.whytheluckystiff.net"
    #
    # To require a library be installed, but not attempt to load it, pass :lib => false
    #
    #   config.gem 'qrp', :version => '0.4.1', :lib => false
    def gem(name, options = {})
      @gems << Rails::GemDependency.new(name, options)
    end

    def default_gems
      []
    end

    def environment_path
      "#{root_path}/config/environments/#{RAILS_ENV}.rb"
    end

    def reload_plugins?
      @reload_plugins
    end
  end
end