module StateMate

Definitions

Declarations

Constants

DIRECTIVES
VERSION

Public Class Methods

array_contains(key, current, value, options) click to toggle source
# File lib/state_mate.rb, line 216
  def self.array_contains key, current, value, options
    case current
    when Array
      # this is just to make the function consistent, so it doesn't add another
      # copy of value if it's there... in practice StateMate should not
      # call {.array_contains} if the value is already in the array
      # (that's what {.array_contains?} tests for)
      if current.include? value
        current
      else
        current + [value]
      end

    when nil
      # it needs to be created
      if options[:create] || options[:clobber]
        [value]
      else
        raise Error::StructureConflictError.new <<-BLOCK.unblock
          can not ensure #{ key.inspect } contains #{ value.inspect } because
          the key does not exist and options[:create] is not true.
        BLOCK
      end

    else
      # there is something there, but it's not an array. out only option
      # to achieve the declared state is to replace it with a new array
      # where value is the only element, but we don't want to do that unless
      # we've been told to clobber
      if options[:clobber]
        [value]
      else
        raise Error::StructureConflictError.new <<-BLOCK.unblock
          can not ensure #{ key.inspect } contains #{ value.inspect } because
          the value is #{ current.inspect } and options[:clobber] is not true.
        BLOCK
      end
    end # case current
  end
array_contains?(key, current, value, adapter, options) click to toggle source
# File lib/state_mate.rb, line 210
def self.array_contains? key, current, value, adapter, options
  current.is_a?(Array) && current.any? {|v|
    values_equal? v, value, adapter
  }
end
array_missing(key, current, value, options) click to toggle source
# File lib/state_mate.rb, line 278
  def self.array_missing key, current, value, options
    case current
    when Array
      current - [value]

    when nil
      # if we're ok with the value being unset (`nil` to us here), then
      # we're done
      if options[:unset_ok]
        nil
      else
        # there is no value, only option is to create a new empty array there
        if options[:create] || options[:clobber]
          []
        else
          raise Error::StructureConflictError.new <<-BLOCK.unblock
            can not ensure #{ key.inspect } missing #{ value.inspect } because
            the key does not exist and options[:create] is not true.
          BLOCK
        end
      end

    else
      # there is something there, but it's not an array. out only option
      # to achieve the declared state is to replace it with a new empty array
      # but we don't want to do that unless we've been told to clobber
      if options[:clobber]
        []
      else
        raise Error::StructureConflictError.new <<-BLOCK.unblock
          can not ensure #{ key.inspect } missing #{ value.inspect } because
          the value is #{ current.inspect } and options[:clobber] is not true.
        BLOCK
      end
    end # case current
  end
array_missing?(key, current, value, adapter, options) click to toggle source

@param options [Hash] @option options [Boolean] :unset_ok if true, the value being unset is

acceptable. many plist files will simply omit the key rather than
store an empty array in the case that an array value is empty,
and setting these to an empty array when all we want to do is make
sure that *if it is there, it doesn't contain the value* seems
pointless.
# File lib/state_mate.rb, line 263
def self.array_missing? key, current, value, adapter, options
  case current
  when nil
    if options[:unset_ok]
      true
    else
      false
    end
  when Array
    !current.any? {|v| values_equal? v, value, adapter}
  else
    false
  end
end
cast(type_name, value) click to toggle source

@api util pure

casts a value to a type, or raises an error if not possible. this is useful because Ansible in particular likes to pass things as strings.

@param type_name [String] the 'name' of the type to cast to. @param value the value to cast.

# File lib/state_mate.rb, line 123
def self.cast type_name, value
  case type_name
  when 'string', 'str'
    value.to_s
  when 'integer', 'int'
    case value
    when Fixnum
      value
    when true
      1
    when false
      0
    when String
      if value =~ /\A[-+]?[0-9]*\Z/
        value.to_i
      elsif value.downcase == 'true'
        1
      elsif value.downcase == 'false'
        0
      else
        raise ArgumentError.new "can't cast to integer: #{ value.inspect }"
      end
    else
      raise TypeError.new "can't cast type to integer: #{ value.inspect }"
    end
  when 'float'
    case value
    when Float
      value
    when Fixnum
      value.to_f
    when String
      if value =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
        value.to_f
      else
        raise ArgumentError.new "can't cast to float: #{ value.inspect }"
      end
    else
      raise TypeError.new "can't cast type to float: #{ value.inspect }"
    end
  when 'boolean', 'bool'
    case value
    when true, false
      value
    when 0, '0', 'False', 'false', 'FALSE'
      false
    when 1, '1', 'True', 'true', 'TRUE'
      true
    else
      raise ArgumentError.new "can't cast type to boolean: #{ value.inspect }"
    end
  else
    raise ArgumentError.new "bad type name: #{ type_name.inspect }"
  end
end
debug(*messages) click to toggle source
# File lib/state_mate.rb, line 94
def self.debug *messages
  return unless @debug
  
  @debug_file ||= File.open('./state_mate.debug.log', @debug_mode)
  
  messages.each_with_index do |message, index|
    if index == 0
      @debug_file.write 'DEBUG '
    end
    
    if message.is_a? String
      @debug_file.puts message
    else
      @debug_file.puts
      PP.pp(message, @debug_file)
    end
  end
end
debug=(mode) click to toggle source

@api dev

turns debug on or off

@param mode [Boolean|String]

if a string, enables and sets the debug file mode (use 'a' or 'w').
if a boolean, sets enabled.
# File lib/state_mate.rb, line 87
def self.debug= mode
  if mode.is_a? String
    @debug_mode = mode
  end
  @debug = !!mode
end
execute(spec) click to toggle source
# File lib/state_mate.rb, line 179
def self.execute spec
  StateSet.from_spec(spec).execute
end
init(key, current, value, options) click to toggle source

when a value needs to be initialized it is simply set to the value.

# File lib/state_mate.rb, line 321
def self.init key, current, value, options
  return value
end
init?(key, current, value, adapter, options) click to toggle source

the value is initialized if it's currently not nil

# File lib/state_mate.rb, line 316
def self.init? key, current, value, adapter, options
  return !current.nil?
end
set(key, current, value, options) click to toggle source
# File lib/state_mate.rb, line 195
def self.set key, current, value, options
  # TODO: handle options
  value
end
set?(key, current, value, adapter, options) click to toggle source
# File lib/state_mate.rb, line 191
def self.set? key, current, value, adapter, options
  values_equal? current, value, adapter
end
unset(key, current, value, options) click to toggle source
# File lib/state_mate.rb, line 204
def self.unset key, current, value, options
  # TODO: handle options
  raise "value most be nil to unset" unless value.nil?
  nil
end
unset?(key, current, value, adapter, options) click to toggle source
# File lib/state_mate.rb, line 200
def self.unset? key, current, value, adapter, options
  current.nil?
end
values_equal?(current, desired, adapter) click to toggle source
# File lib/state_mate.rb, line 183
def self.values_equal? current, desired, adapter
  if adapter.respond_to? :values_equal?
    adapter.values_equal? current, desired
  else
    current == desired
  end
end