5 $LOAD_PATH.unshift File.dirname(__FILE__)
6 require 'railties_path'
7 require 'rails/version'
8 require 'rails/plugin/locator'
9 require 'rails/plugin/loader'
12 RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
15 # The Initializer is responsible for processing the Rails configuration, such
16 # as setting the $LOAD_PATH, requiring the right frameworks, initializing
17 # logging, and more. It can be run either as a single command that'll just
18 # use the default configuration, like this:
20 # Rails::Initializer.run
22 # But normally it's more interesting to pass in a custom configuration
23 # through the block running:
25 # Rails::Initializer.run do |config|
26 # config.frameworks -= [ :action_mailer ]
29 # This will use the default configuration options from Rails::Configuration,
30 # but allow for overwriting on select areas.
32 # The Configuration instance used by this Initializer instance.
33 attr_reader :configuration
35 # The set of loaded plugins.
36 attr_reader :loaded_plugins
38 # Runs the initializer. By default, this will invoke the #process method,
39 # which simply executes all of the initialization routines. Alternately,
40 # you can specify explicitly which initialization routine you want:
42 # Rails::Initializer.run(:set_load_path)
44 # This is useful if you only want the load path initialized, without
45 # incuring the overhead of completely loading the entire environment.
46 def self.run(command = :process, configuration = Configuration.new)
47 yield configuration if block_given?
48 initializer = new configuration
49 initializer.send(command)
53 # Create a new Initializer instance that references the given Configuration
55 def initialize(configuration)
56 @configuration = configuration
60 # Sequentially step through all of the available initialization routines,
63 # * #check_ruby_version
65 # * #require_frameworks
66 # * #set_autoload_paths
67 # * add_plugin_load_paths
69 # * #initialize_encoding
70 # * #initialize_database
71 # * #initialize_logger
72 # * #initialize_framework_logging
73 # * #initialize_framework_views
74 # * #initialize_dependency_mechanism
75 # * #initialize_whiny_nils
76 # * #initialize_temporary_directories
77 # * #initialize_framework_settings
78 # * #add_support_load_paths
81 # * #initialize_routing
83 # * #load_application_initializers
96 initialize_framework_logging
97 initialize_framework_views
98 initialize_dependency_mechanism
100 initialize_temporary_directories
101 initialize_framework_settings
103 add_support_load_paths
107 # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
110 # Routing must be initialized after plugins to allow the former to extend the routes
113 # the framework is now fully initialized
116 load_application_initializers
119 # Check for valid Ruby version
120 # This is done in an external file, so we can use it
121 # from the `rails` program as well without duplication.
122 def check_ruby_version
123 require 'ruby_version_check'
126 # Set the <tt>$LOAD_PATH</tt> based on the value of
127 # Configuration#load_paths. Duplicates are removed.
129 load_paths = configuration.load_paths + configuration.framework_paths
130 load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
134 # Set the paths from which Rails will automatically load source files, and
135 # the load_once paths.
136 def set_autoload_paths
137 Dependencies.load_paths = configuration.load_paths.uniq
138 Dependencies.load_once_paths = configuration.load_once_paths.uniq
140 extra = Dependencies.load_once_paths - Dependencies.load_paths
143 load_once_paths must be a subset of the load_paths.
144 Extra items in load_once_paths: #{extra * ','}
148 # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
149 configuration.load_once_paths.freeze
152 # Requires all frameworks specified by the Configuration#frameworks
153 # list. By default, all frameworks (ActiveRecord, ActiveSupport,
154 # ActionPack, ActionMailer, and ActiveResource) are loaded.
155 def require_frameworks
156 configuration.frameworks.each { |framework| require(framework.to_s) }
157 rescue LoadError => e
158 # re-raise because Mongrel would swallow it
162 # Add the load paths used by support functions such as the info controller
163 def add_support_load_paths
166 # Adds all load paths from plugins to the global set of load paths, so that
167 # code from plugins can be required (explicitly or automatically via Dependencies).
168 def add_plugin_load_paths
169 plugin_loader.add_plugin_load_paths
172 # Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
173 # defaults to <tt>vendor/plugins</tt> but may also be set to a list of
175 # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]
177 # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized:
178 # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory)
179 # * <tt>init.rb</tt> is evalutated, if present
181 # After all plugins are loaded, duplicates are removed from the load path.
182 # If an array of plugin names is specified in config.plugins, only those plugins will be loaded
183 # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical
186 # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other
187 # plugins will be loaded in alphabetical order
189 plugin_loader.load_plugins
193 @plugin_loader ||= configuration.plugin_loader.new(self)
196 # Loads the environment specified by Configuration#environment_path, which
197 # is typically one of development, test, or production.
200 return if @environment_loaded
201 @environment_loaded = true
203 config = configuration
204 constants = self.class.constants
206 eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
208 (self.class.constants - constants).each do |const|
209 Object.const_set(const, self.class.const_get(const))
215 if configuration.frameworks.include?(:active_record)
216 ActiveRecord::Base.instantiate_observers
220 # This initialzation sets $KCODE to 'u' to enable the multibyte safe operations.
221 # Plugin authors supporting other encodings should override this behaviour and
222 # set the relevant +default_charset+ on ActionController::Base
223 def initialize_encoding
227 # This initialization routine does nothing unless <tt>:active_record</tt>
228 # is one of the frameworks to load (Configuration#frameworks). If it is,
229 # this sets the database configuration from Configuration#database_configuration
230 # and then establishes the connection.
231 def initialize_database
232 if configuration.frameworks.include?(:active_record)
233 ActiveRecord::Base.configurations = configuration.database_configuration
234 ActiveRecord::Base.establish_connection
238 # If the +RAILS_DEFAULT_LOGGER+ constant is already set, this initialization
239 # routine does nothing. If the constant is not set, and Configuration#logger
240 # is not +nil+, this also does nothing. Otherwise, a new logger instance
241 # is created at Configuration#log_path, with a default log level of
242 # Configuration#log_level.
244 # If the log could not be created, the log will be set to output to
245 # +STDERR+, with a log level of +WARN+.
246 def initialize_logger
247 # if the environment has explicitly defined a logger, use it
248 return if defined?(RAILS_DEFAULT_LOGGER)
250 unless logger = configuration.logger
252 logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
253 logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
254 logger.auto_flushing = false if configuration.environment == "production"
255 rescue StandardError =>e
256 logger = ActiveSupport::BufferedLogger.new(STDERR)
257 logger.level = ActiveSupport::BufferedLogger::WARN
259 "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
260 "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
265 silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
268 # Sets the logger for ActiveRecord, ActionController, and ActionMailer
269 # (but only for those frameworks that are to be loaded). If the framework's
270 # logger is already set, it is not changed, otherwise it is set to use
271 # +RAILS_DEFAULT_LOGGER+.
272 def initialize_framework_logging
273 for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
274 framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER
278 # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
279 # (but only for those frameworks that are to be loaded). If the framework's
280 # paths have already been set, it is not changed, otherwise it is
281 # set to use Configuration#view_path.
282 def initialize_framework_views
283 ActionMailer::Base.template_root ||= configuration.view_path if configuration.frameworks.include?(:action_mailer)
284 ActionController::Base.view_paths = [configuration.view_path] if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.empty?
287 # If ActionController is not one of the loaded frameworks (Configuration#frameworks)
288 # this does nothing. Otherwise, it loads the routing definitions and sets up
289 # loading module used to lazily load controllers (Configuration#controller_paths).
290 def initialize_routing
291 return unless configuration.frameworks.include?(:action_controller)
292 ActionController::Routing.controller_paths = configuration.controller_paths
293 ActionController::Routing::Routes.reload
296 # Sets the dependency loading mechanism based on the value of
297 # Configuration#cache_classes.
298 def initialize_dependency_mechanism
299 Dependencies.mechanism = configuration.cache_classes ? :require : :load
302 # Loads support for "whiny nil" (noisy warnings when methods are invoked
303 # on +nil+ values) if Configuration#whiny_nils is true.
304 def initialize_whiny_nils
305 require('active_support/whiny_nil') if configuration.whiny_nils
308 def initialize_temporary_directories
309 if configuration.frameworks.include?(:action_controller)
310 session_path = "#{configuration.root_path}/tmp/sessions/"
311 ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir
313 cache_path = "#{configuration.root_path}/tmp/cache/"
314 if File.exist?(cache_path)
315 ActionController::Base.fragment_cache_store = :file_store, cache_path
320 # Initializes framework-specific settings for each of the loaded frameworks
321 # (Configuration#frameworks). The available settings map to the accessors
322 # on each of the corresponding Base classes.
323 def initialize_framework_settings
324 configuration.frameworks.each do |framework|
325 base_class = framework.to_s.camelize.constantize.const_get("Base")
327 configuration.send(framework).each do |setting, value|
328 base_class.send("#{setting}=", value)
333 # Fires the user-supplied after_initialize block (Configuration#after_initialize)
335 configuration.after_initialize_blocks.each do |block|
340 def load_application_initializers
341 Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
348 # The Configuration class holds all the parameters for the Initializer and
349 # ships with defaults that suites most Rails applications. But it's possible
350 # to overwrite everything. Usually, you'll create an Configuration file
351 # implicitly through the block running on the Initializer, but it's also
352 # possible to create the Configuration instance in advance and pass it in
355 # config = Rails::Configuration.new
356 # Rails::Initializer.run(:process, config)
358 # The application's base directory.
359 attr_reader :root_path
361 # A stub for setting options on ActionController::Base
362 attr_accessor :action_controller
364 # A stub for setting options on ActionMailer::Base
365 attr_accessor :action_mailer
367 # A stub for setting options on ActionView::Base
368 attr_accessor :action_view
370 # A stub for setting options on ActiveRecord::Base
371 attr_accessor :active_record
373 # A stub for setting options on ActiveRecord::Base
374 attr_accessor :active_resource
376 # Whether or not classes should be cached (set to false if you want
377 # application classes to be reloaded on each request)
378 attr_accessor :cache_classes
380 # The list of paths that should be searched for controllers. (Defaults
381 # to <tt>app/controllers</tt> and <tt>components</tt>.)
382 attr_accessor :controller_paths
384 # The path to the database configuration file to use. (Defaults to
385 # <tt>config/database.yml</tt>.)
386 attr_accessor :database_configuration_file
388 # The list of rails framework components that should be loaded. (Defaults
389 # to <tt>:active_record</tt>, <tt>:action_controller</tt>,
390 # <tt>:action_view</tt>, <tt>:action_mailer</tt>, and
391 # <tt>:active_resource</tt>).
392 attr_accessor :frameworks
394 # An array of additional paths to prepend to the load path. By default,
395 # all +app+, +lib+, +vendor+ and mock paths are included in this list.
396 attr_accessor :load_paths
398 # An array of paths from which Rails will automatically load from only once.
399 # All elements of this array must also be in +load_paths+.
400 attr_accessor :load_once_paths
402 # The log level to use for the default Rails logger. In production mode,
403 # this defaults to <tt>:info</tt>. In development mode, it defaults to
405 attr_accessor :log_level
407 # The path to the log file to use. Defaults to log/#{environment}.log
408 # (e.g. log/development.log or log/production.log).
409 attr_accessor :log_path
411 # The specific logger to use. By default, a logger will be created and
412 # initialized using #log_path and #log_level, but a programmer may
413 # specifically set the logger to use via this accessor and it will be
415 attr_accessor :logger
417 # The root of the application's views. (Defaults to <tt>app/views</tt>.)
418 attr_accessor :view_path
420 # Set to +true+ if you want to be warned (noisily) when you try to invoke
421 # any method of +nil+. Set to +false+ for the standard Ruby behavior.
422 attr_accessor :whiny_nils
424 # The list of plugins to load. If this is set to <tt>nil</tt>, all plugins will
425 # be loaded. If this is set to <tt>[]</tt>, no plugins will be loaded. Otherwise,
426 # plugins will be loaded in the order specified.
428 def plugins=(plugins)
429 @plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym }
432 # The path to the root of the plugins directory. By default, it is in
433 # <tt>vendor/plugins</tt>.
434 attr_accessor :plugin_paths
436 # The classes that handle finding the desired plugins that you'd like to load for
437 # your application. By default it is the Rails::Plugin::FileSystemLocator which finds
438 # plugins to load in <tt>vendor/plugins</tt>. You can hook into gem location by subclassing
439 # Rails::Plugin::Locator and adding it onto the list of <tt>plugin_locators</tt>.
440 attr_accessor :plugin_locators
442 # The class that handles loading each plugin. Defaults to Rails::Plugin::Loader, but
443 # a sub class would have access to fine grained modification of the loading behavior. See
444 # the implementation of Rails::Plugin::Loader for more details.
445 attr_accessor :plugin_loader
447 # Deprecated options:
448 def breakpoint_server(_ = nil)
450 *******************************************************************
451 * config.breakpoint_server has been deprecated and has no effect. *
452 *******************************************************************
455 alias_method :breakpoint_server=, :breakpoint_server
457 # Create a new Configuration instance, initialized with the default
462 self.frameworks = default_frameworks
463 self.load_paths = default_load_paths
464 self.load_once_paths = default_load_once_paths
465 self.log_path = default_log_path
466 self.log_level = default_log_level
467 self.view_path = default_view_path
468 self.controller_paths = default_controller_paths
469 self.cache_classes = default_cache_classes
470 self.whiny_nils = default_whiny_nils
471 self.plugins = default_plugins
472 self.plugin_paths = default_plugin_paths
473 self.plugin_locators = default_plugin_locators
474 self.plugin_loader = default_plugin_loader
475 self.database_configuration_file = default_database_configuration_file
477 for framework in default_frameworks
478 self.send("#{framework}=", Rails::OrderedOptions.new)
482 # Set the root_path to RAILS_ROOT and canonicalize it.
484 raise 'RAILS_ROOT is not set' unless defined?(::RAILS_ROOT)
485 raise 'RAILS_ROOT is not a directory' unless File.directory?(::RAILS_ROOT)
488 # Pathname is incompatible with Windows, but Windows doesn't have
489 # real symlinks so File.expand_path is safe.
490 if RUBY_PLATFORM =~ /(:?mswin|mingw)/
491 File.expand_path(::RAILS_ROOT)
493 # Otherwise use Pathname#realpath which respects symlinks.
495 Pathname.new(::RAILS_ROOT).realpath.to_s
498 Object.const_set(:RELATIVE_RAILS_ROOT, ::RAILS_ROOT.dup) unless defined?(::RELATIVE_RAILS_ROOT)
499 ::RAILS_ROOT.replace @root_path
502 # Loads and returns the contents of the #database_configuration_file. The
503 # contents of the file are processed via ERB before being sent through
505 def database_configuration
506 YAML::load(ERB.new(IO.read(database_configuration_file)).result)
509 # The path to the current environment's file (development.rb, etc.). By
510 # default the file is at <tt>config/environments/#{environment}.rb</tt>.
512 "#{root_path}/config/environments/#{environment}.rb"
515 # Return the currently selected environment. By default, it returns the
516 # value of the +RAILS_ENV+ constant.
521 # Adds a block which will be executed after rails has been fully initialized.
522 # Useful for per-environment configuration which depends on the framework being
524 def after_initialize(&after_initialize_block)
525 after_initialize_blocks << after_initialize_block if after_initialize_block
528 # Returns the blocks added with Configuration#after_initialize
529 def after_initialize_blocks
530 @after_initialize_blocks ||= []
533 # Add a preparation callback that will run before every request in development
534 # mode, or before the first request in production.
536 # See Dispatcher#to_prepare.
537 def to_prepare(&callback)
538 require 'dispatcher' unless defined?(::Dispatcher)
539 Dispatcher.to_prepare(&callback)
542 def builtin_directories
543 # Include builtins only in the development environment.
544 (environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
548 paths = %w(railties railties/lib activesupport/lib)
549 paths << 'actionpack/lib' if frameworks.include? :action_controller or frameworks.include? :action_view
551 [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
552 paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include? framework
555 paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
559 def framework_root_path
560 defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails"
563 def default_frameworks
564 [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
567 def default_load_paths
568 paths = ["#{root_path}/test/mocks/#{environment}"]
570 # Add the app's controller directory
571 paths.concat(Dir["#{root_path}/app/controllers/"])
573 # Then components subdirectories.
574 paths.concat(Dir["#{root_path}/components/[_a-z]*"])
576 # Followed by the standard includes.
587 ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
589 paths.concat builtin_directories
592 # Doesn't matter since plugins aren't in load_paths yet.
593 def default_load_once_paths
598 File.join(root_path, 'log', "#{environment}.log")
601 def default_log_level
602 environment == 'production' ? :info : :debug
605 def default_database_configuration_file
606 File.join(root_path, 'config', 'database.yml')
609 def default_view_path
610 File.join(root_path, 'app', 'views')
613 def default_controller_paths
614 paths = [File.join(root_path, 'app', 'controllers')]
615 paths.concat builtin_directories
619 def default_dependency_mechanism
623 def default_cache_classes
627 def default_whiny_nils
635 def default_plugin_paths
636 ["#{root_path}/vendor/plugins"]
639 def default_plugin_locators
640 [Plugin::FileSystemLocator]
643 def default_plugin_loader
649 # Needs to be duplicated from Active Support since its needed before Active
650 # Support is available. Here both Options and Hash are namespaced to prevent
651 # conflicts with other implementations AND with the classes residing in ActiveSupport.
652 class Rails::OrderedOptions < Array #:nodoc:
656 if pair = find_pair(key)
665 pair = find_pair(key.to_sym)
666 pair ? pair.last : nil
669 def method_missing(name, *args)
670 if name.to_s =~ /(.*)=$/
671 self[$1.to_sym] = args.first
679 self.each { |i| return i if i.first == key }