Respect indentation / spacing for existing sections and settings
This commit adds some cosmetic functionality. The main two improvements are: * We'll now pay attention to indentation within existing sections, and when we write new settings or update existing ones, we'll match the existing indentation. * When modifying existing settings, the regex now captures a greater portion of the original line and preserves it. Basically, the original whitespacing in the line should remain intact and only the value should be modified.
This commit is contained in:
parent
a5eebcfca0
commit
c2c26de9b1
3 changed files with 214 additions and 13 deletions
|
@ -6,7 +6,7 @@ module Util
|
|||
class IniFile
|
||||
|
||||
SECTION_REGEX = /^\s*\[([\w\d\.\\\/\-\:]+)\]\s*$/
|
||||
SETTING_REGEX = /^\s*([\w\d\.\\\/\-]+)\s*=\s*([\S\s]*\S)\s*$/
|
||||
SETTING_REGEX = /^(\s*)([\w\d\.\\\/\-]+)(\s*=\s*)([\S\s]*\S)\s*$/
|
||||
|
||||
def initialize(path, key_val_separator = ' = ')
|
||||
@path = path
|
||||
|
@ -30,7 +30,7 @@ module Util
|
|||
|
||||
def set_value(section_name, setting, value)
|
||||
unless (@sections_hash.has_key?(section_name))
|
||||
add_section(Section.new(section_name, nil, nil, nil))
|
||||
add_section(Section.new(section_name, nil, nil, nil, nil))
|
||||
end
|
||||
|
||||
section = @sections_hash[section_name]
|
||||
|
@ -77,7 +77,7 @@ module Util
|
|||
end
|
||||
|
||||
section.additional_settings.each_pair do |key, value|
|
||||
fh.puts("#{key}#{@key_val_separator}#{value}")
|
||||
fh.puts("#{' ' * (section.indentation || 0)}#{key}#{@key_val_separator}#{value}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -111,12 +111,15 @@ module Util
|
|||
def read_section(name, start_line, line_iter)
|
||||
settings = {}
|
||||
end_line_num = nil
|
||||
min_indentation = nil
|
||||
while true
|
||||
line, line_num = line_iter.peek
|
||||
if (line_num.nil? or match = SECTION_REGEX.match(line))
|
||||
return Section.new(name, start_line, end_line_num, settings)
|
||||
return Section.new(name, start_line, end_line_num, settings, min_indentation)
|
||||
elsif (match = SETTING_REGEX.match(line))
|
||||
settings[match[1]] = match[2]
|
||||
settings[match[2]] = match[4]
|
||||
indentation = match[1].length
|
||||
min_indentation = [indentation, min_indentation || indentation].min
|
||||
end
|
||||
end_line_num = line_num
|
||||
line_iter.next
|
||||
|
@ -126,8 +129,8 @@ module Util
|
|||
def update_line(section, setting, value)
|
||||
(section.start_line..section.end_line).each do |line_num|
|
||||
if (match = SETTING_REGEX.match(lines[line_num]))
|
||||
if (match[1] == setting)
|
||||
lines[line_num] = "#{setting}#{@key_val_separator}#{value}"
|
||||
if (match[2] == setting)
|
||||
lines[line_num] = "#{match[1]}#{match[2]}#{match[3]}#{value}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -136,7 +139,7 @@ module Util
|
|||
def remove_line(section, setting)
|
||||
(section.start_line..section.end_line).each do |line_num|
|
||||
if (match = SETTING_REGEX.match(lines[line_num]))
|
||||
if (match[1] == setting)
|
||||
if (match[2] == setting)
|
||||
lines.delete_at(line_num)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,15 +2,16 @@ module Puppet
|
|||
module Util
|
||||
class IniFile
|
||||
class Section
|
||||
def initialize(name, start_line, end_line, settings)
|
||||
def initialize(name, start_line, end_line, settings, indentation)
|
||||
@name = name
|
||||
@start_line = start_line
|
||||
@end_line = end_line
|
||||
@existing_settings = settings.nil? ? {} : settings
|
||||
@additional_settings = {}
|
||||
@indentation = indentation
|
||||
end
|
||||
|
||||
attr_reader :name, :start_line, :end_line, :additional_settings
|
||||
attr_reader :name, :start_line, :end_line, :additional_settings, :indentation
|
||||
|
||||
def get_value(setting_name)
|
||||
@existing_settings[setting_name] || @additional_settings[setting_name]
|
||||
|
|
|
@ -123,7 +123,7 @@ master = true
|
|||
[section2]
|
||||
|
||||
foo= foovalue2
|
||||
baz = bazvalue2
|
||||
baz=bazvalue2
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
|
@ -154,7 +154,7 @@ foo= foovalue2
|
|||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby = foo
|
||||
subby=foo
|
||||
#another comment
|
||||
; yet another comment
|
||||
EOS
|
||||
|
@ -329,7 +329,7 @@ foo = http://192.168.1.1:8080
|
|||
provider.value=('yippee')
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
foo = yippee
|
||||
foo=yippee
|
||||
[section2]
|
||||
foo = http://192.168.1.1:8080
|
||||
; yet another comment
|
||||
|
@ -533,4 +533,201 @@ subby=bar
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
context "when dealing with indentation in sections" do
|
||||
let(:orig_content) {
|
||||
<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
EOS
|
||||
}
|
||||
|
||||
it "should add a missing setting at the correct indentation when the header is aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(common_params.merge(
|
||||
:section => 'section1', :setting => 'yahoo', :value => 'yippee'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_nil
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
yahoo = yippee
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
it "should update an existing setting at the correct indentation when the header is aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(
|
||||
common_params.merge(:section => 'section1', :setting => 'bar', :value => 'barvalue2'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_true
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue2
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
it "should add a missing setting at the correct indentation when the header is not aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(common_params.merge(
|
||||
:section => 'section2', :setting => 'yahoo', :value => 'yippee'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_nil
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
yahoo = yippee
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
it "should update an existing setting at the correct indentation when the header is not aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(
|
||||
common_params.merge(:section => 'section2', :setting => 'baz', :value => 'bazvalue2'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_true
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue2
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
it "should add a missing setting at the min indentation when the section is not aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(
|
||||
common_params.merge(:section => 'section:sub', :setting => 'yahoo', :value => 'yippee'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_nil
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam
|
||||
; yet another comment
|
||||
yahoo = yippee
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
it "should update an existing setting at the previous indentation when the section is not aligned" do
|
||||
resource = Puppet::Type::Ini_setting.new(
|
||||
common_params.merge(:section => 'section:sub', :setting => 'fleezy', :value => 'flam2'))
|
||||
provider = described_class.new(resource)
|
||||
provider.exists?.should be_true
|
||||
provider.create
|
||||
validate_file(<<-EOS
|
||||
# This is a comment
|
||||
[section1]
|
||||
; This is also a comment
|
||||
foo=foovalue
|
||||
|
||||
bar = barvalue
|
||||
master = true
|
||||
|
||||
[section2]
|
||||
foo= foovalue2
|
||||
baz=bazvalue
|
||||
url = http://192.168.1.1:8080
|
||||
[section:sub]
|
||||
subby=bar
|
||||
#another comment
|
||||
fleezy = flam2
|
||||
; yet another comment
|
||||
EOS
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue