116 lines
4.4 KiB
Ruby

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
module Vagrant
module Plugin
module V1
# This is the base class for a configuration key defined for
# V1. Any configuration key plugins for V1 should inherit from this
# class.
class Config
# This constant represents an unset value. This is useful so it is
# possible to know the difference between a configuration value that
# was never set, and a value that is nil (explicitly). Best practice
# is to initialize all variables to this value, then the {#merge}
# method below will "just work" in many cases.
UNSET_VALUE = Object.new
# This is called as a last-minute hook that allows the configuration
# object to finalize itself before it will be put into use. This is
# a useful place to do some defaults in the case the user didn't
# configure something or so on.
#
# An example of where this sort of thing is used or has been used:
# the "vm" configuration key uses this to make sure that at least
# one sub-VM has been defined: the default VM.
#
# The configuration object is expected to mutate itself.
def finalize!
# Default implementation is to do nothing.
end
# Merge another configuration object into this one. This assumes that
# the other object is the same class as this one. This should not
# mutate this object, but instead should return a new, merged object.
#
# The default implementation will simply iterate over the instance
# variables and merge them together, with this object overriding
# any conflicting instance variables of the older object. Instance
# variables starting with "__" (double underscores) will be ignored.
# This lets you set some sort of instance-specific state on your
# configuration keys without them being merged together later.
#
# @param [Object] other The other configuration object to merge from,
# this must be the same type of object as this one.
# @return [Object] The merged object.
def merge(other)
result = self.class.new
# Set all of our instance variables on the new class
[self, other].each do |obj|
obj.instance_variables.each do |key|
# Ignore keys that start with a double underscore. This allows
# configuration classes to still hold around internal state
# that isn't propagated.
if !key.to_s.start_with?("@__")
result.instance_variable_set(key, obj.instance_variable_get(key))
end
end
end
result
end
# Allows setting options from a hash. By default this simply calls
# the `#{key}=` method on the config class with the value, which is
# the expected behavior most of the time.
#
# This is expected to mutate itself.
#
# @param [Hash] options A hash of options to set on this configuration
# key.
def set_options(options)
options.each do |key, value|
send("#{key}=", value)
end
end
# Converts this configuration object to JSON.
def to_json(*a)
instance_variables_hash.to_json(*a)
end
# Returns the instance variables as a hash of key-value pairs.
def instance_variables_hash
instance_variables.inject({}) do |acc, iv|
acc[iv.to_s[1..-1]] = instance_variable_get(iv)
acc
end
end
# This is called to upgrade this V1 config to V2. The parameter given
# is the full V2 configuration object, so you can do anything to it
# that you want.
#
# No return value is expected, modifications should be made directly
# to the new V2 object.
#
# @param [V2::Root] new
def upgrade(new)
end
# Called after the configuration is finalized and loaded to validate
# this object.
#
# @param [Environment] env Vagrant::Environment object of the
# environment that this configuration has been loaded into. This
# gives you convenient access to things like the the root path
# and so on.
# @param [ErrorRecorder] errors
def validate(env, errors)
end
end
end
end
end