Class: Nucleon::Config

Inherits:
Object
  • Object
show all
Extended by:
Mixin::ConfigCollection, Mixin::ConfigOptions
Defined in:
lib/core/config.rb,
lib/core/config/options.rb,
lib/core/config/collection.rb

Overview

for easier initialization of configurations.

Direct Known Subclasses

Core

Defined Under Namespace

Classes: Collection, Options

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ConfigOptions

all_options, clear_options, contexts, get_options, set_options

Methods included from Mixin::ConfigCollection

all_properties, clear_properties, delete_property, get_property, save_properties, set_property

Constructor Details

#initialize(data = {}, defaults = {}, force = true, basic_merge = true) ⇒ Config

Initialize a new configuration object with given options and defaults.

The defaults are split out from the original options because we have found it handy to have them initialized from two different data objects. Defaults are only set if the original data lacks the default property name.

The configuration object is ultimately designed to provide a starting point for creating distributed objects, which are easily loaded, dumped, and merged to form composite objects.

The configuration serves as the framework base class to all Nucleon plugins, core objects, and a few utilities. This class is the most important object in the entire Nucleon framework, as it is used the most.

Example:

config = Nucleon::Config.new({ :other_property => 'something' }, {
  :my_property => 'default',
  :other_property => 'default'
})
config.export
# {
#   :my_property => 'default',
#   :other_property => 'something'
# }
  • Parameters

    • nil, Hash, Nucleon::Config

      data Configurations to evaluate and possibly convert

    • Hash

      defaults Configuration defaults that may be overridden by config data

    • Boolean

      force Whether or not to force override of values where types don’t match during merge

    • Boolean

      basic_merge Whether or not to perform a basic merge or deep (recursive) merge

  • Returns

    • Nucleon::Config

      Returns configuration object

  • Errors

See also:

  • ::ensure

  • ::init

  • ::init_flat

  • #symbol_map

  • #export

  • Nucleon::Util::Data::merge



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/core/config.rb', line 236

def initialize(data = {}, defaults = {}, force = true, basic_merge = true)
  @force       = force
  @basic_merge = basic_merge
  @properties  = {}

  if defaults.is_a?(Hash) && ! defaults.empty?
    defaults = symbol_map(Util::Data.clone(defaults))
  end

  case data
  when Nucleon::Config
    @properties = Util::Data.merge([ defaults, data.export ], force, basic_merge)
  when Hash
    @properties = {}
    if data.is_a?(Hash)
      @properties = Util::Data.merge([ defaults, symbol_map(Util::Data.clone(data)) ], force, basic_merge)
    end
  else
    @properties = defaults if defaults.is_a?(Hash)
  end
end

Class Method Details

.array(data, default = [], split_string = false) ⇒ Object

Ensure a data object is an array.

See:

  • Nucleon::Util::Data::array



904
905
906
# File 'lib/core/config.rb', line 904

def self.array(data, default = [], split_string = false)
  return Util::Data.array(data, default, split_string)
end

.ensure(config, defaults = {}, force = true, basic_merge = true) ⇒ Object

Ensure the return of a Nucleon::Config object based on different inputs.

This method can also initialize defaults for the configuration object if the configurations do not exist yet.

For example: (you will see variants of this pattern everywhere)

def some_method(options = {})
  # Options might be a Config object or Hash?
  config = Config.ensure(options, { :my_property => 'default value' })
  prop   = config[:my_property]
end
  • Parameters

    • nil, Hash, Nucleon::Config

      config Configurations to evaluate and possibly convert

    • Hash

      defaults Configuration defaults that may be overridden by config data

    • Boolean

      force Whether or not to force override of values where types don’t match during merge

    • Boolean

      basic_merge Whether or not to perform a basic merge or deep (recursive) merge

  • Returns

    • Nucleon::Config

      Returns configuration object

  • Errors

See:

  • ::new

  • #defaults



93
94
95
96
97
98
99
100
101
# File 'lib/core/config.rb', line 93

def self.ensure(config, defaults = {}, force = true, basic_merge = true)
  case config
  when Nucleon::Config
    return config.defaults(defaults, { :force => force, :basic => basic_merge })
  when Hash
    return new(config, defaults, force, basic_merge)
  end
  return new({}, defaults, force, basic_merge)
end

.filter(data, method = false) ⇒ Object

Run a defined filter on a data object.

This method ensures that a given data object meets some criteria or else an empty value for that type is returned that matches the criteria.

Currently implemented filters:

  1. ::array Ensure result is an array (non arrays are converted)

  2. ::hash Ensure result is a hash (non hashes are converted)

  3. ::string Ensure result is a string (non strings are converted)

  4. ::symbol Ensure result is a symbol (non symbols are converted)

  5. ::test Ensure result is not empty (runs a boolean ::empty? check)

See:

  • Nucleon::Util::Data::filter



884
885
886
# File 'lib/core/config.rb', line 884

def self.filter(data, method = false)
  return Util::Data.filter(data, method)
end

.hash(data, default = {}) ⇒ Object

Ensure a data object is a hash.

See:

  • Nucleon::Util::Data::hash



922
923
924
925
# File 'lib/core/config.rb', line 922

def self.hash(data, default = {})
  data = data.export if data.is_a?(Nucleon::Config)
  return Util::Data.hash(data, default)
end

.init(options, contexts = [], hierarchy = [], defaults = {}, force = true, basic_merge = true) ⇒ Object

Initialize a new configuration object with contextualized defaults from the global configuration option collection.

This method is not really used much within Nucleon itself, but is used to help create the corl gem Puppet interface that forms the provisioner configurations for resource creation based on options defined in Puppet.

This method supports hierarchical lookup of context properties.

Example:

Nucleon::Config::set_options([ :context1, :prefix_context2 ], { :my_property => 'value' })

config = Nucleon::Config.init({ :other_property => 'something' }, :context2, :prefix)
config.export
# {
#   :my_property => 'value',
#   :other_property => 'something'
# }
  • Parameters

    • nil, Hash, Nucleon::Config

      config Configurations to evaluate and possibly convert

    • Array<String, Symbol>, String, Symbol

      contexts Context names to include in list

    • Array<String, Symbol>, String, Symbol

      hierarchy Hierarchy of prefixes to apply to given contexts

    • Hash

      defaults Configuration defaults that may be overridden by config data

    • Boolean

      force Whether or not to force override of values where types don’t match during merge

    • Boolean

      basic_merge Whether or not to perform a basic merge or deep (recursive) merge

  • Returns

    • Nucleon::Config

      Returns configuration object

  • Errors

See also:

  • Nucleon::Config::Options

  • Nucleon::Mixin::ConfigOptions#contexts

  • Nucleon::Mixin::ConfigOptions#get_options

  • ::new

  • #import

  • Util::Data::empty?



144
145
146
147
148
149
# File 'lib/core/config.rb', line 144

def self.init(options, contexts = [], hierarchy = [], defaults = {}, force = true, basic_merge = true)
  contexts = contexts(contexts, hierarchy)
  config   = new(get_options(contexts), defaults, force, basic_merge)
  config.import(options) unless Util::Data.empty?(options)
  return config
end

.init_flat(options, contexts = [], defaults = {}, force = true, basic_merge = true) ⇒ Object

Initialize a new configuration object with contextualized defaults from the global configuration option collection (no hierarchical support).

This method is not really used much within Nucleon itself, but is used to help create the corl gem Puppet interface that forms the provisioner configurations for resource creation based on options defined in Puppet.

Example:

Nucleon::Config::set_options([ :context1, :context2 ], { :my_property => 'value' })

config = Nucleon::Config.init_flat({ :other_property => 'something' }, :context2)
config.export
# {
#   :my_property => 'value',
#   :other_property => 'something'
# }
  • Parameters

    • nil, Hash, Nucleon::Config

      config Configurations to evaluate and possibly convert

    • Array<String, Symbol>, String, Symbol

      contexts Context names to include in list

    • Hash

      defaults Configuration defaults that may be overridden by config data

    • Boolean

      force Whether or not to force override of values where types don’t match during merge

    • Boolean

      basic_merge Whether or not to perform a basic merge or deep (recursive) merge

  • Returns

    • Nucleon::Config

      Returns configuration object

  • Errors

See:

  • ::init



184
185
186
# File 'lib/core/config.rb', line 184

def self.init_flat(options, contexts = [], defaults = {}, force = true, basic_merge = true)
  return init(options, contexts, [], defaults, force, basic_merge)
end

.string(data, default = '') ⇒ Object

Ensure a data object is a string.

See:

  • Nucleon::Util::Data::string



941
942
943
# File 'lib/core/config.rb', line 941

def self.string(data, default = '')
  return Util::Data.string(data, default)
end

.string_map(data) ⇒ Object

Return hash as a string map.

This method converts all hash keys to strings. Nested hashes are recursively translated as well.

This comes in really handy when performing operations across hashes in Ruby because of the distinction between symbols and strings.

See:

  • Nucleon::Util::Data::string_map



854
855
856
# File 'lib/core/config.rb', line 854

def self.string_map(data)
  return Util::Data.string_map(data)
end

.symbol(data, default = :undefined) ⇒ Object

Ensure a data object is a symbol.

See:

  • Nucleon::Util::Data::symbol



959
960
961
# File 'lib/core/config.rb', line 959

def self.symbol(data, default = :undefined)
  return Util::Data.symbol(data, default)
end

.symbol_map(data) ⇒ Object

Return hash as a symbol map.

This method converts all hash keys to symbols. Nested hashes are recursively translated as well.

This comes in really handy when performing operations across hashes in Ruby because of the distinction between symbols and strings.

See:

  • Nucleon::Util::Data::symbol_map



812
813
814
# File 'lib/core/config.rb', line 812

def self.symbol_map(data)
  return Util::Data.symbol_map(data)
end

.test(data) ⇒ Object

Test a data object for emptiness and return boolean result.

See:

  • Nucleon::Util::Data::test



977
978
979
# File 'lib/core/config.rb', line 977

def self.test(data)
  return Util::Data.test(data)
end

Instance Method Details

#[](name, default = nil, format = false) ⇒ Object

Fetch value for key path in the configuration object.

This method is really just to provide an easier interface compatible with Hash access for simpler configuration groups.

  • Parameters

    • String, Symbol

      name Key to fetch

    • ANY

      default Default value is no value is found for key

    • false, Symbol, String

      format Format to filter final returned value or false for none

  • Returns

    • ANY

      Filtered value for key path from configuration object

  • Errors

See:

  • #get



459
460
461
# File 'lib/core/config.rb', line 459

def [](name, default = nil, format = false)
  get(name, default, format)
end

#[]=(name, value) ⇒ Object

Set value for key in the configuration object.

This method is really just to provide an easier interface compatible with Hash access for simpler configuration groups.

  • Parameters

    • String, Symbol

      name Key to fetch

    • ANY

      value Value to set for key

  • Returns

    • Void

      Return value thrown away

  • Errors

See:

  • #set



631
632
633
# File 'lib/core/config.rb', line 631

def []=(name, value)
  set(name, value)
end

#append(keys, value) ⇒ Object

Append a value for an array key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to modify

    • ANY

      value Value to set for key path

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

See:

  • #modify

See also:

  • #array



572
573
574
575
576
577
578
579
580
581
# File 'lib/core/config.rb', line 572

def append(keys, value)
  modify(@properties, symbol_array(array(keys).flatten), value, false) do |key, processed_value, existing|
    if existing.is_a?(Array)
      [ existing, processed_value ].flatten
    else
      [ processed_value ]
    end
  end
  return self
end

#array(data, default = [], split_string = false) ⇒ Object

Ensure a data object is an array.

See:

  • ::array



913
914
915
# File 'lib/core/config.rb', line 913

def array(data, default = [], split_string = false)
  return self.class.array(data, default, split_string)
end

#clearObject

Clear all properties from the configuration object.

  • Parameters

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors



667
668
669
670
# File 'lib/core/config.rb', line 667

def clear
  @properties = {}
  return self
end

#defaults(defaults, options = {}) ⇒ Object

Set default property values in the configuration object if they don’t exist.

If defaults are given as a string or symbol and the configuration object has a lookup method implemented (corl gem) then the defaults will be dynamically looked up and set.

  • Parameters

    • String, Symbol, Array, Hash

      defaults Data to set as defaults

    • Hash

      options Import options

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

See:

  • #import_base

See also:

  • ::new

  • #set



780
781
782
783
# File 'lib/core/config.rb', line 780

def defaults(defaults, options = {})
  config = Config.new(options).set(:import_type, :default)
  return import_base(defaults, config)
end

#delete(keys, default = nil) ⇒ Object

Delete key path from the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to remove

    • ANY

      default Default value to return if no existing value found

  • Returns

    • ANY

      Returns default or last value removed from configuration object

  • Errors

See:

  • #modify

See also:

  • #array



652
653
654
655
656
# File 'lib/core/config.rb', line 652

def delete(keys, default = nil)
  existing = modify(@properties, symbol_array(array(keys).flatten), nil, true)
  return existing[:value] unless existing[:value].nil?
  return default
end

#empty?Boolean

Check whether or not this configuration object is empty.

  • Parameters

  • Returns

    • Boolean

      Whether or not configuration object is empty

  • Errors

Returns:

  • (Boolean)


270
271
272
# File 'lib/core/config.rb', line 270

def empty?
  @properties.empty?
end

#exportObject

Export properties into a regular hash object (cloned)

  • Parameters

  • Returns

    • Hash

      Returns a hash of all the configuration properties

  • Errors



794
795
796
# File 'lib/core/config.rb', line 794

def export
  return Util::Data.clone(@properties)
end

#filter(data, method = false) ⇒ Object

Run a defined filter on a data object.

See:

  • ::filter



893
894
895
# File 'lib/core/config.rb', line 893

def filter(data, method = false)
  return self.class.filter(data, method)
end

#get(keys, default = nil, format = false) ⇒ Object

Fetch value for key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to fetch

    • ANY

      default Default value is no value is found for key path

    • false, Symbol, String

      format Format to filter final returned value or false for none

  • Returns

    • ANY

      Filtered value for key path from configuration object

  • Errors

See:

  • #fetch

See also:

  • #array



437
438
439
# File 'lib/core/config.rb', line 437

def get(keys, default = nil, format = false)
  return fetch(@properties, symbol_array(array(keys).flatten), default, format)
end

#get_array(keys, default = []) ⇒ Object

Fetch filtered array value for key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to fetch

    • Array

      default Default value is no value is found for key path

  • Returns

    • Array

      Filtered array value for key path from configuration object

  • Errors

See:

  • #get

See also:

  • #array

  • Nucleon::Util::Data::array



481
482
483
# File 'lib/core/config.rb', line 481

def get_array(keys, default = [])
  return get(keys, default, :array)
end

#get_hash(keys, default = {}) ⇒ Object

Fetch filtered hash value for key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to fetch

    • Hash

      default Default hash value is no value is found for key path

  • Returns

    • Hash

      Filtered hash value for key path from configuration object

  • Errors

See:

  • #get

See also:

  • #hash

  • Nucleon::Util::Data::hash



503
504
505
# File 'lib/core/config.rb', line 503

def get_hash(keys, default = {})
  return get(keys, default, :hash)
end

#has_key?(keys) ⇒ Boolean

Check whether or not this configuration object has a specific key.

The purpose of this method is to provide a complimentary has_key? method to the Hash class so we can check either interchangeably.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to check

  • Returns

    • Boolean

      Whether or not configuration object has a specific key

  • Errors

See:

  • #get

Returns:

  • (Boolean)


290
291
292
# File 'lib/core/config.rb', line 290

def has_key?(keys)
  get(keys).nil? ? false : true
end

#hash(data, default = {}) ⇒ Object

Ensure a data object is a hash

See:

  • ::hash



932
933
934
# File 'lib/core/config.rb', line 932

def hash(data, default = {})
  return self.class.hash(data, default)
end

#import(properties, options = {}) ⇒ Object

Import new property values into the configuration object. (override)

If properties are given as a string or symbol and the configuration object has a lookup method implemented (corl gem) then the properties will be dynamically looked up and imported.

  • Parameters

    • String, Symbol, Array, Hash

      properties Data to import

    • Hash

      options Import options

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

See:

  • #import_base



754
755
756
# File 'lib/core/config.rb', line 754

def import(properties, options = {})
  return import_base(properties, options)
end

#init(keys, default = nil) ⇒ Object

Initialize value for key path in the configuration object if one does not exist yet.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to modify

    • ANY

      default Default value to set for key path if it does not exist yet

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

See:

  • #get

  • #set



523
524
525
# File 'lib/core/config.rb', line 523

def init(keys, default = nil)
  return set(keys, get(keys, default))
end

#keysObject

Return all of the keys for the configuration properties hash.

The purpose of this method is to provide a complimentary keys method to the Hash class so we can return either interchangeably.

  • Parameters

  • Returns

    • Array<Symbol>

      Array of existing configuration properties

  • Errors



309
310
311
# File 'lib/core/config.rb', line 309

def keys
  @properties.keys
end

#prepend(keys, value, reverse = false) ⇒ Object

Prepend a value to an array key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to modify

    • ANY

      value Value to set for key path

    • Boolean

      reverse Whether or not to reverse any input value arrays given before prepending

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

See:

  • #modify

See also:

  • #array



601
602
603
604
605
606
607
608
609
610
611
612
# File 'lib/core/config.rb', line 601

def prepend(keys, value, reverse = false)
  modify(@properties, symbol_array(array(keys).flatten), value, false) do |key, processed_value, existing|
    processed_value = processed_value.reverse if reverse && processed_value.is_a?(Array)

    if existing.is_a?(Array)
      [ processed_value, existing ].flatten
    else
      [ processed_value ]
    end
  end
  return self
end

#set(keys, value, delete_nil = false, &code) ⇒ Object

Set value for key path in the configuration object.

  • Parameters

    • Array<String, Symbol>, String, Symbol

      keys Key path to modify

    • ANY

      value Value to set for key path

    • Boolean

      delete_nil Delete nil value (serves as an internal way to delete properties)

  • Returns

    • Nucleon::Config

      Returns reference to self for compound operations

  • Errors

  • Yields

    • Symbol

      key Configuration key to modify

    • ANY

      value New value of configuration key

    • ANY

      existing Existing value being replaced for the configuration key

See:

  • #modify

See also:

  • #array



550
551
552
553
# File 'lib/core/config.rb', line 550

def set(keys, value, delete_nil = false, &code) # :yields: key, value, existing
  modify(@properties, symbol_array(array(keys).flatten), value, delete_nil, &code)
  return self
end

#string(data, default = '') ⇒ Object

Ensure a data object is a string.

See:

  • ::string



950
951
952
# File 'lib/core/config.rb', line 950

def string(data, default = '')
  return self.class.string(data, default)
end

#string_map(data) ⇒ Object

Return hash as a string map.

See:

  • ::string_map



863
864
865
# File 'lib/core/config.rb', line 863

def string_map(data)
  return self.class.string_map(data)
end

#symbol(data, default = :undefined) ⇒ Object

Ensure a data object is a symbol.

See:

  • ::symbol



968
969
970
# File 'lib/core/config.rb', line 968

def symbol(data, default = :undefined)
  return self.class.symbol(data, default)
end

#symbol_array(array) ⇒ Object

Return a symbolized array

  • Parameters

    • Array<String, Symbol>

      array Array of strings or symbols

  • Returns

    • Array<Symbol>

      Returns array of symbols

  • Errors



835
836
837
838
839
840
841
# File 'lib/core/config.rb', line 835

def symbol_array(array)
  result = []
  array.each do |item|
    result << item.to_sym unless item.nil?
  end
  result
end

#symbol_map(data) ⇒ Object

Return hash as a symbol map.

See:

  • ::symbol_map



821
822
823
# File 'lib/core/config.rb', line 821

def symbol_map(data)
  return self.class.symbol_map(data)
end

#test(data) ⇒ Object

Test a data object for emptiness and return boolean result.

See:

  • ::test



986
987
988
# File 'lib/core/config.rb', line 986

def test(data)
  return self.class.test(data)
end