Class: PuppetX::IniFile

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/puppet_x/twp/inifile.rb

Overview

This class represents the INI file and can be used to parse, modify, and write INI files.

Defined Under Namespace

Classes: Error, Parser

Constant Summary collapse

VERSION =
'3.0.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ IniFile

Public: Create a new INI file from the given set of options. If :content is provided then it will be used to populate the INI file. If a :filename is provided then the contents of the file will be parsed and stored in the INI file. If neither the :content or :filename is provided then an empty INI file is created.

opts - The Hash of options (default: {})

:content   - The String/Hash containing the INI contents
:comment   - String containing the comment character(s)
:parameter - String used to separate parameter and value
:encoding  - Encoding String for reading / writing
:default   - The String name of the default global section
:filename  - The filename as a String

Examples

IniFile.new
#=> an empty IniFile instance

IniFile.new( :content => "[global]\nfoo=bar" )
#=> an IniFile instance

IniFile.new( :filename => 'file.ini', :encoding => 'UTF-8' )
#=> an IniFile instance

IniFile.new( :content => "[global]\nfoo=bar", :comment => '#' )
#=> an IniFile instance


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/puppet_x/twp/inifile.rb', line 75

def initialize(opts = {})
  @comment  = opts.fetch(:comment, '#')
  @param    = opts.fetch(:parameter, '=')
  @encoding = opts.fetch(:encoding, nil)
  @default  = opts.fetch(:default, 'global')
  @filename = opts.fetch(:filename, nil)
  content   = opts.fetch(:content, nil)

  @ini = Hash.new { |h, k| h[k] = {} }

  if    content.is_a?(Hash) then merge!(content)
  elsif content             then parse(content)
  elsif @filename           then read
  end
end

Instance Attribute Details

#encodingObject

Get and set the encoding



45
46
47
# File 'lib/puppet_x/twp/inifile.rb', line 45

def encoding
  @encoding
end

#filenameObject

Get and set the filename



42
43
44
# File 'lib/puppet_x/twp/inifile.rb', line 42

def filename
  @filename
end

Class Method Details

.load(filename, opts = {}) ⇒ Object

Public: Open an INI file and load the contents.

filename - The name of the file as a String opts - The Hash of options (default: {})

:comment   - String containing the comment character(s)
:parameter - String used to separate parameter and value
:encoding  - Encoding String for reading / writing
:default   - The String name of the default global section

Examples

IniFile.load('file.ini')
#=> IniFile instance

IniFile.load('does/not/exist.ini')
#=> nil

Returns an IniFile instance or nil if the file could not be opened.



35
36
37
38
39
# File 'lib/puppet_x/twp/inifile.rb', line 35

def self.load(filename, opts = {})
  return unless File.file? filename

  new(opts.merge(filename: filename))
end

Instance Method Details

#[](section) ⇒ Object

Public: Get the section Hash by name. If the section does not exist, then it will be created.

section - The section name as a String.

Examples

inifile['global']
#=> global section Hash

Returns the Hash of parameter/value pairs for this section.



275
276
277
278
279
# File 'lib/puppet_x/twp/inifile.rb', line 275

def [](section)
  return nil if section.nil?

  @ini[section.to_s]
end

#[]=(section, value) ⇒ Object

Public: Set the section to a hash of parameter/value pairs.

section - The section name as a String. value - The Hash of parameter/value pairs.

Examples

inifile['tenderloin'] = { 'gritty' => 'yes' }
#=> { 'gritty' => 'yes' }

Returns the value Hash.



292
293
294
# File 'lib/puppet_x/twp/inifile.rb', line 292

def []=(section, value)
  @ini[section.to_s] = value
end

#cloneObject

Public: Produces a duplicate of this IniFile. The duplicate is independent of the original – i.e. the duplicate can be modified without changing the original. The tainted state and the frozen state of the original is copied to the duplicate.

Returns a new IniFile.



367
368
369
370
371
# File 'lib/puppet_x/twp/inifile.rb', line 367

def clone
  other = dup
  other.freeze if frozen?
  other
end

#delete_section(section) ⇒ Object

Public: Remove a section identified by name from the IniFile.

section - The section name as a String.

Returns the deleted section Hash.



260
261
262
# File 'lib/puppet_x/twp/inifile.rb', line 260

def delete_section(section)
  @ini.delete section.to_s
end

#dupObject

Public: Produces a duplicate of this IniFile. The duplicate is independent of the original – i.e. the duplicate can be modified without changing the original. The tainted state of the original is copied to the duplicate.

Returns a new IniFile.



353
354
355
356
357
358
359
# File 'lib/puppet_x/twp/inifile.rb', line 353

def dup
  other = super
  other.instance_variable_set(:@ini, Hash.new { |h, k| h[k] = {} })
  @ini.each_pair { |s, h| other[s].merge! h }
  other.taint if tainted?
  other
end

#eachObject

Public: Yield each INI file section, parameter, and value in turn to the given block.

block - The block that will be iterated by the each method. The block will

be passed the current section and the parameter/value pair.

Examples

inifile.each do |section, parameter, value|
  puts "#{parameter} = #{value} [in section - #{section}]"
end

Returns this IniFile.



225
226
227
228
229
230
231
232
233
234
# File 'lib/puppet_x/twp/inifile.rb', line 225

def each
  return unless block_given?

  @ini.each do |section, hash|
    hash.each do |param, val|
      yield section, param, val
    end
  end
  self
end

#each_section(&block) ⇒ Object

Public: Yield each section in turn to the given block.

block - The block that will be iterated by the each method. The block will

be passed the current section as a Hash.

Examples

inifile.each_section do |section|
  puts section.inspect
end

Returns this IniFile.



248
249
250
251
252
253
# File 'lib/puppet_x/twp/inifile.rb', line 248

def each_section(&block)
  return unless block_given?

  @ini.each_key(&block)
  self
end

#eql?(other) ⇒ Boolean Also known as: ==

Public: Compare this IniFile to some other IniFile. For two INI files to be equivalent, they must have the same sections with the same parameter / value pairs in each section.

other - The other IniFile.

Returns true if the INI files are equivalent and false if they differ.

Returns:

  • (Boolean)


380
381
382
383
384
385
# File 'lib/puppet_x/twp/inifile.rb', line 380

def eql?(other)
  return true if equal? other
  return false unless other.instance_of? self.class

  @ini == other.instance_variable_get(:@ini)
end

#escape_value(value) ⇒ Object

Escape special characters.

value - The String value to escape.

Returns the escaped value.



393
394
395
396
397
398
399
400
401
# File 'lib/puppet_x/twp/inifile.rb', line 393

def escape_value(value)
  value = value.to_s.dup
  value.gsub!(%r{\\([0nrt])}, '\\\\\1')
  value.gsub!(%r{\n}, '\n')
  value.gsub!(%r{\r}, '\r')
  value.gsub!(%r{\t}, '\t')
  value.gsub!(%r{\0}, '\0')
  value
end

#freezeObject

Public: Freeze the state of this IniFile object. Any attempts to change the object will raise an error.

Returns this IniFile.



330
331
332
333
334
335
# File 'lib/puppet_x/twp/inifile.rb', line 330

def freeze
  super
  @ini.each_value { |h| h.freeze }
  @ini.freeze
  self
end

#match(regex) ⇒ Object

Public: Create a Hash containing only those INI file sections whose names match the given regular expression.

regex - The Regexp used to match section names.

Examples

inifile.match(/^tree_/)
#=> Hash of matching sections

Return a Hash containing only those sections that match the given regular expression.



308
309
310
# File 'lib/puppet_x/twp/inifile.rb', line 308

def match(regex)
  @ini.dup.delete_if { |section, _| section !~ regex }
end

#merge(other) ⇒ Object

Public: Creates a copy of this inifile with the entries from the other_inifile merged into the copy.

other - The other IniFile.

Returns a new IniFile.



163
164
165
# File 'lib/puppet_x/twp/inifile.rb', line 163

def merge(other)
  dup.merge!(other)
end

#merge!(other) ⇒ Object

Public: Merges other_inifile into this inifile, overwriting existing entries. Useful for having a system inifile with user overridable settings elsewhere.

other - The other IniFile.

Returns this IniFile.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/puppet_x/twp/inifile.rb', line 174

def merge!(other)
  return self if other.nil?

  my_keys = @ini.keys
  other_keys = case other
               when IniFile
                 other.instance_variable_get(:@ini).keys
               when Hash
                 other.keys
               else
                 raise Error, "cannot merge contents from '#{other.class.name}'"
               end

  (my_keys & other_keys).each do |key|
    case other[key]
    when Hash
      @ini[key].merge!(other[key])
    when nil
      nil
    else
      raise Error, "cannot merge section #{key.inspect} - unsupported type: #{other[key].class.name}"
    end
  end

  (other_keys - my_keys).each do |key|
    @ini[key] = case other[key]
                when Hash
                  other[key].dup
                when nil
                  {}
                else
                  raise Error, "cannot merge section #{key.inspect} - unsupported type: #{other[key].class.name}"
                end
  end

  self
end

#parse(content) ⇒ Object

Parse the given content and store the information in this IniFile instance. All data will be cleared out and replaced with the information read from the content.

content - A String or a file descriptor (must respond to ‘each_line`)

Returns this IniFile.



410
411
412
413
414
# File 'lib/puppet_x/twp/inifile.rb', line 410

def parse(content)
  parser = Parser.new(@ini, @param, @comment, @default)
  parser.parse(content)
  self
end

#read(opts = {}) ⇒ Object Also known as: restore

Public: Read the contents of the INI file from the file system and replace and set the state of this IniFile instance. If left unspecified the currently configured filename and encoding will be used when reading from the file system. Otherwise the filename and encoding can be specified in the options hash.

opts - The default options Hash

:filename - The filename as a String
:encoding - The encoding as a String

Returns this IniFile instance if the read was successful; nil is returned if the file could not be read.



129
130
131
132
133
134
135
136
137
138
# File 'lib/puppet_x/twp/inifile.rb', line 129

def read(opts = {})
  filename = opts.fetch(:filename, @filename)
  encoding = opts.fetch(:encoding, @encoding)
  return unless File.file? filename

  mode = encoding ? "r:#{encoding}" : 'r'

  File.open(filename, mode) { |fd| parse fd }
  self
end

#section?(section) ⇒ Boolean

Public: Check to see if the IniFile contains the section.

section - The section name as a String.

Returns true if the section exists in the IniFile.

Returns:

  • (Boolean)


317
318
319
# File 'lib/puppet_x/twp/inifile.rb', line 317

def section?(section)
  @ini.key? section.to_s
end

#sectionsObject

Returns an Array of section names contained in this IniFile.



322
323
324
# File 'lib/puppet_x/twp/inifile.rb', line 322

def sections
  @ini.keys
end

#taintObject

Public: Mark this IniFile as tainted – this will traverse each section marking each as tainted.

Returns this IniFile.



341
342
343
344
345
346
# File 'lib/puppet_x/twp/inifile.rb', line 341

def taint
  super
  @ini.each_value { |h| h.taint }
  @ini.taint
  self
end

#to_hObject

Returns this IniFile converted to a Hash.



153
154
155
# File 'lib/puppet_x/twp/inifile.rb', line 153

def to_h
  @ini.dup
end

#to_sObject

Returns this IniFile converted to a String.



142
143
144
145
146
147
148
149
150
# File 'lib/puppet_x/twp/inifile.rb', line 142

def to_s
  s = []
  @ini.each do |section, hash|
    s << "[#{section}]"
    hash.each { |param, val| s << "#{param} #{@param} #{escape_value val}" }
    s << ''
  end
  s.join("\n")
end

#write(opts = {}) ⇒ Object Also known as: save

Public: Write the contents of this IniFile to the file system. If left unspecified, the currently configured filename and encoding will be used. Otherwise the filename and encoding can be specified in the options hash.

opts - The default options Hash

:filename - The filename as a String
:encoding - The encoding as a String

Returns this IniFile instance.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/puppet_x/twp/inifile.rb', line 100

def write(opts = {})
  filename = opts.fetch(:filename, @filename)
  encoding = opts.fetch(:encoding, @encoding)
  mode = encoding ? "w:#{encoding}" : 'w'

  File.open(filename, mode) do |f|
    @ini.each do |section, hash|
      f.puts "[#{section}]"
      hash.each { |param, val| f.puts "#{param} #{@param} #{escape_value val}" }
      f.puts
    end
  end

  self
end