class OctofactsUpdater::Fact

Attributes

name[R]

Public Class Methods

new(name, value) click to toggle source

Constructor.

name - The String naming the fact. value - The arbitrary object with the value of the fact.

# File lib/octofacts_updater/fact.rb, line 15
def initialize(name, value)
  @name = name
  @value = value
end

Public Instance Methods

set_value(new_value, name_in = nil) click to toggle source

Set the value of the fact. If the name is specified, this will dig into a structured fact to set the value within the structure.

new_value - An object with the new value for the fact

name_in - An optional String to dig into the structure (formatted with

indicating hash delimiters)

# File lib/octofacts_updater/fact.rb, line 58
def set_value(new_value, name_in = nil)
  if name_in.nil?
    if new_value.is_a?(Proc)
      return @value = new_value.call(@value)
    end

    return @value = new_value
  end

  parts = if name_in.is_a?(String)
    name_in.split("::")
  elsif name_in.is_a?(Array)
    name_in.map do |item|
      if item.is_a?(String)
        item
      elsif item.is_a?(Hash) && item.key?("regexp")
        Regexp.new(item["regexp"])
      else
        raise ArgumentError, "Unable to interpret structure item: #{item.inspect}"
      end
    end
  else
    raise ArgumentError, "Unable to interpret structure: #{name_in.inspect}"
  end

  set_structured_value(@value, parts, new_value)
end
value(name_in = nil) click to toggle source

Get the value of the fact. If the name is specified, this will dig into a structured fact to pull out the value within the structure.

name_in - An optional String to dig into the structure (formatted with

indicating hash delimiters)

Returns the value of the fact.

# File lib/octofacts_updater/fact.rb, line 26
def value(name_in = nil)
  # Just a normal lookup -- return the value
  return @value if name_in.nil?

  # Structured lookup returns nil unless the fact is actually structured.
  return unless @value.is_a?(Hash)

  # Dig into the hash to pull out the desired value.
  pointer = @value
  parts = name_in.split("::")
  last_part = parts.pop

  parts.each do |part|
    return unless pointer[part].is_a?(Hash)
    pointer = pointer[part]
  end

  pointer[last_part]
end
value=(new_value) click to toggle source

Set the value of the fact.

new_value - An object with the new value for the fact

# File lib/octofacts_updater/fact.rb, line 49
def value=(new_value)
  set_value(new_value)
end

Private Instance Methods

set_structured_value(subhash, parts, value) click to toggle source

Set a value in the data structure of a structured fact. This is intended to be called recursively.

subhash - The Hash, part of the fact, being operated upon parts - The Array to dig in to the hash value - The value to set the ultimate last part to

Does not return anything, but modifies 'subhash'

# File lib/octofacts_updater/fact.rb, line 96
def set_structured_value(subhash, parts, value)
  return if subhash.nil?
  raise ArgumentError, "Cannot set structured value at #{parts.first.inspect}" unless subhash.is_a?(Hash)
  raise ArgumentError, "parts must be an Array, got #{parts.inspect}" unless parts.is_a?(Array)

  # At the top level, find all keys that match the first item in the parts.
  matching_keys = subhash.keys.select do |key|
    if parts.first.is_a?(String)
      key == parts.first
    elsif parts.first.is_a?(Regexp)
      parts.first.match(key)
    else
      # :nocov:
      # This is a bug - this code should be unreachable because of the checking in `set_value`
      raise ArgumentError, "part must be a string or regexp, got #{parts.first.inspect}"
      # :nocov:
    end
  end

  # Auto-create a new hash if there is a value, the part is a string, and the key doesn't exist.
  if parts.first.is_a?(String) && !value.nil? && !subhash.key?(parts.first)
    subhash[parts.first] = {}
    matching_keys << parts.first
  end
  return unless matching_keys.any?

  # If we are at the end, set the value or delete the key.
  if parts.size == 1
    if value.nil?
      matching_keys.each { |k| subhash.delete(k) }
    elsif value.is_a?(Proc)
      matching_keys.each do |k|
        new_value = value.call(subhash[k])
        if new_value.nil?
          subhash.delete(k)
        else
          subhash[k] = new_value
        end
      end
    else
      matching_keys.each { |k| subhash[k] = value }
    end
    return
  end

  # We are not at the end. Recurse down to the next level.
  matching_keys.each { |k| set_structured_value(subhash[k], parts[1..-1], value) }
end