Mitchell Hashimoto 1a8c4199b2 Introduce Config::Loader
Config::Loader will be the new class responsible for loading configuration
and replaces the previous dual-role "Vagrant::Config" played. While this
commit is very early-stage, once this new architecture is flushed out, it
will make loading, using, and extending configuration much easier and cleaner.

Additionally, I believe this will help post Vagrant 1.0 if multi-language
configuration is implemented.
2011-12-03 17:12:48 -08:00

62 lines
2.2 KiB
Ruby

module Vagrant
module Config
# This class is the "top" configure class, which handles registering
# other configuration classes as well as validation of all configured
# classes. This is the object which is returned by {Environment#config}
# and has accessors to all other configuration classes.
#
# If you're looking to create your own configuration class, see {Base}.
class Top < Base
@@configures = {} if !defined?(@@configures)
# The environment that this configuration is for.
attr_reader :env
class << self
# The list of registered configuration classes as well as the key
# they're registered under.
def configures_list
@@configures ||= {}
end
# Registers a configuration class with the given key. This method shouldn't
# be called. Instead, inherit from {Base} and call {Base.configures}.
def configures(key, klass)
configures_list[key] = klass
attr_reader key.to_sym
end
end
def initialize(env=nil)
self.class.configures_list.each do |key, klass|
config = klass.new
config.top = self
instance_variable_set("@#{key}".to_sym, config)
end
@env = env
end
# Validates the configuration classes of this instance and raises an
# exception if they are invalid. If you are implementing a custom configuration
# class, the method you want to implement is {Base#validate}. This is
# the method that checks all the validation, not one which defines
# validation rules.
def validate!
# Validate each of the configured classes and store the results into
# a hash.
errors = self.class.configures_list.inject({}) do |container, data|
key, _ = data
recorder = ErrorRecorder.new
send(key.to_sym).validate(recorder)
container[key.to_sym] = recorder if !recorder.errors.empty?
container
end
return if errors.empty?
raise Errors::ConfigValidationFailed, :messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors)
end
end
end
end