Class: Vagrant::Plugin::V2::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant/plugin/v2/config.rb

Overview

This is the base class for a configuration key defined for V2. Any configuration key plugins for V2 should inherit from this class.

Constant Summary collapse

UNSET_VALUE =

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.

Object.new

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Capture all bad configuration calls and save them for an error message later during validation.



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/vagrant/plugin/v2/config.rb', line 72

def method_missing(name, *args, &block)
  return super if @__finalized

  name = name.to_s
  name = name[0...-1] if name.end_with?("=")

  @__invalid_methods ||= Set.new
  @__invalid_methods.add(name)

  # Return the dummy object so that anything else works
  ::Vagrant::Config::V2::DummyConfig.new
end

Instance Method Details

#_detected_errorsArray<String>

This returns any automatically detected errors.

Returns:

  • (Array<String>)


130
131
132
133
134
# File 'lib/vagrant/plugin/v2/config.rb', line 130

def _detected_errors
  return [] if !@__invalid_methods || @__invalid_methods.empty?
  return [I18n.t("vagrant.config.common.bad_field",
                 fields: @__invalid_methods.to_a.sort.join(", "))]
end

#_finalize!Object

An internal finalize call that no subclass should override.



137
138
139
# File 'lib/vagrant/plugin/v2/config.rb', line 137

def _finalize!
  @__finalized = true
end

#finalize!Object

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.



27
28
29
# File 'lib/vagrant/plugin/v2/config.rb', line 27

def finalize!
  # Default implementation is to do nothing.
end

#instance_variables_hashObject

Returns the instance variables as a hash of key-value pairs.



110
111
112
113
114
115
# File 'lib/vagrant/plugin/v2/config.rb', line 110

def instance_variables_hash
  instance_variables.inject({}) do |acc, iv|
    acc[iv.to_s[1..-1]] = instance_variable_get(iv)
    acc
  end
end

#merge(other) ⇒ Object

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.

Parameters:

  • other (Object)

    The other configuration object to merge from, this must be the same type of object as this one.

Returns:

  • (Object)

    The merged object.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/vagrant/plugin/v2/config.rb', line 45

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?("@__")
        # Don't set the value if it is the unset value, either.
        value = obj.instance_variable_get(key)
        result.instance_variable_set(key, value) if value != UNSET_VALUE
      end
    end
  end

  # Persist through the set of invalid methods
  this_invalid  = @__invalid_methods || Set.new
  other_invalid = other.instance_variable_get(:"@__invalid_methods") || Set.new
  result.instance_variable_set(:"@__invalid_methods", this_invalid + other_invalid)

  result
end

#set_options(options) ⇒ Object

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.

Parameters:

  • options (Hash)

    A hash of options to set on this configuration key.



93
94
95
96
97
# File 'lib/vagrant/plugin/v2/config.rb', line 93

def set_options(options)
  options.each do |key, value|
    send("#{key}=", value)
  end
end

#to_json(*a) ⇒ Object

Converts this configuration object to JSON.



100
101
102
# File 'lib/vagrant/plugin/v2/config.rb', line 100

def to_json(*a)
  instance_variables_hash.to_json(*a)
end

#to_sObject

A default to_s implementation.



105
106
107
# File 'lib/vagrant/plugin/v2/config.rb', line 105

def to_s
  self.class.to_s
end

#validate(machine) ⇒ Hash

Called after the configuration is finalized and loaded to validate this object.

Parameters:

  • machine (Machine)

    Access to the machine that is being validated.

Returns:

  • (Hash)


123
124
125
# File 'lib/vagrant/plugin/v2/config.rb', line 123

def validate(machine)
  return { self.to_s => _detected_errors }
end