class CFA::AugeasTree

Represents a parsed Augeas config tree with user friendly methods

Public Class Methods

new() click to toggle source
# File lib/cfa/augeas_parser.rb, line 220
def initialize
  @data = []
end

Public Instance Methods

==(other) click to toggle source
# File lib/cfa/augeas_parser.rb, line 301
def ==(other)
  return false if self.class != other.class

  other_data = other.data # do not compute again
  data.each_with_index do |entry, index|
    other_entry = other_data[index]
    return false unless other_entry
    return false if entry[:key] != other_entry[:key]
    return false if entry[:value] != other_entry[:value]
  end

  true
end
Also aliased as: eql?
[](key) click to toggle source

Finds given key in tree. @param key [String] @return [String,AugeasTree,AugeasTreeValue,nil] the first value for key,

or `nil` if not found
# File lib/cfa/augeas_parser.rb, line 277
def [](key)
  entry = @data.find { |d| d[:key] == key && d[:operation] != :remove }
  return entry[:value] if entry

  nil
end
[]=(key, value) click to toggle source

Replace the first value for key with value. Append a new element if key did not exist. If key was previously removed, then put it back to its old position. @param key [String] @param value [String, AugeasTree, AugeasTreeValue]

# File lib/cfa/augeas_parser.rb, line 289
def []=(key, value)
  new_entry = entry_to_modify(key, value)
  new_entry[:key] = key
  new_entry[:value] = value
end
add(key, value, placer = AppendPlacer.new) click to toggle source

Adds the given value for key in the tree.

By default an AppendPlacer is used which produces duplicate keys but ReplacePlacer can be used to replace the first duplicate. @param key [String] @param value [String,AugeasTree,AugeasTreeValue] @param placer [Placer] determines where to insert value in tree.

Useful e.g. to specify order of keys or placing comment above of given
key.
# File lib/cfa/augeas_parser.rb, line 266
def add(key, value, placer = AppendPlacer.new)
  element = placer.new_element(self)
  element[:key] = key
  element[:value] = value
  element[:operation] = :add
end
all_data() click to toggle source

low level access to all AugeasElement including ones marked for removal

# File lib/cfa/augeas_parser.rb, line 216
def all_data
  @data
end
collection(key) click to toggle source

@return [AugeasCollection] collection for key

# File lib/cfa/augeas_parser.rb, line 239
def collection(key)
  AugeasCollection.new(self, key)
end
data() click to toggle source

Low level access to Augeas structure

An ordered mapping, represented by an Array of AugeasElement, but without any removed elements.

@see AugeasElement

@return [Array<Hash{Symbol => Object}>] a frozen array as it is

just a copy of the real data
# File lib/cfa/augeas_parser.rb, line 211
def data
  @data.reject { |e| e[:operation] == :remove }.freeze
end
delete(matcher) click to toggle source

@param [String, Matcher] matcher

# File lib/cfa/augeas_parser.rb, line 244
def delete(matcher)
  return if matcher.nil?

  unless matcher.is_a?(CFA::Matcher)
    matcher = CFA::Matcher.new(key: matcher)
  end
  to_remove = @data.select(&matcher)

  to_delete, to_mark = to_remove.partition { |e| e[:operation] == :add }
  @data -= to_delete
  to_mark.each { |e| e[:operation] = :remove }
end
eql?(other)

For objects of class Object, eql? is synonymous with ==: ruby-doc.org/core-2.3.3/Object.html#method-i-eql-3F

Alias for: ==
select(matcher) click to toggle source

@param matcher [Matcher] @return [Array<AugeasElement>] matching elements

# File lib/cfa/augeas_parser.rb, line 297
def select(matcher)
  data.select(&matcher)
end
unique_id() click to toggle source

Gets new unique id in numberic sequence. Useful for augeas models that using sequences like /etc/hosts . It have keys like “1”, “2” and when adding new one it need to find new key.

# File lib/cfa/augeas_parser.rb, line 227
def unique_id
  # check all_data instead of data, as we have to not reuse deleted key
  ids = Set.new(all_data.map { |e| e[:key] })
  id = 1
  loop do
    return id.to_s unless ids.include?(id.to_s)

    id += 1
  end
end

Private Instance Methods

entry_to_modify(key, value) click to toggle source
# File lib/cfa/augeas_parser.rb, line 347
def entry_to_modify(key, value)
  entry = @data.find { |d| d[:key] == key }
  # we are switching from tree to value or treevalue to value only
  # like change from key=value to key=value#comment
  if entry && entry[:value].class != value.class
    entry = replace_entry(entry)
  end
  new_entry = entry || {}
  mark_new_entry(new_entry, entry)

  @data << new_entry unless entry

  new_entry
end
mark_new_entry(new_entry, old_entry) click to toggle source
# File lib/cfa/augeas_parser.rb, line 337
def mark_new_entry(new_entry, old_entry)
  # if an entry already exists then just modify it,
  # but only if we previously did not add it
  new_entry[:operation] = if old_entry && old_entry[:operation] != :add
                            :modify
                          else
                            :add
                          end
end
replace_entry(old_entry) click to toggle source
# File lib/cfa/augeas_parser.rb, line 321
def replace_entry(old_entry)
  index = @data.index(old_entry)
  new_entry = { operation: :add }
  # insert the replacement to the same location
  @data.insert(index, new_entry)
  # the entry is not yet in the tree
  if old_entry[:operation] == :add
    key = old_entry[:key]
    @data.delete_if { |d| d[:key] == key }
  else
    old_entry[:operation] = :remove
  end

  new_entry
end