Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple values per key #481

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/puppet/provider/ini_subsetting/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def ini_file

def setting_value
@setting_value ||= Puppet::Util::SettingValue.new(
ini_file.get_value(section, setting),
Array(ini_file.get_value(section, setting))[0],
subsetting_separator, quote_char, subsetting_key_val_separator
)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/type/ini_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def munge_boolean_md5(value)
defaultto(' = ')
end

newproperty(:value) do
newproperty(:value, array_matching: :all) do
desc 'The value of the setting to be defined.'

munge do |value|
Expand Down
50 changes: 37 additions & 13 deletions lib/puppet/util/ini_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def set_value(*args)
(section_name, setting, separator, value) = args
end

value = [*value]

complete_setting = {
setting: setting,
separator: separator,
Expand All @@ -79,8 +81,17 @@ def set_value(*args)
section = @sections_hash[section_name]

if section.existing_setting?(setting)
existing_value = section.get_value(setting)
section_index = @section_names.index(section_name)

update_line(section, setting, value)
section.update_existing_setting(setting, value)

if value.length > existing_value.length
increment_section_line_numbers(section_index + 1, value.length - existing_value.length)
elsif value.length < existing_value.length
decrement_section_line_numbers(section_index + 1, existing_value.length - value.length)
end
elsif find_commented_setting(section, setting)
# So, this stanza is a bit of a hack. What we're trying
# to do here is this: for settings that don't already
Expand All @@ -101,7 +112,7 @@ def set_value(*args)
# numbers for all of the sections *after* the one that
# was modified.
section_index = @section_names.index(section_name)
increment_section_line_numbers(section_index + 1)
increment_section_line_numbers(section_index + 1, value.length)
elsif !setting.nil? || !value.nil?
section.set_additional_setting(setting, value)
end
Expand All @@ -110,6 +121,8 @@ def set_value(*args)
def remove_setting(section_name, setting)
section = @sections_hash[section_name]
return unless section.existing_setting?(setting)
existing_value = section.get_value(setting)

# If the setting is found, we have some work to do.
# First, we remove the line from our array of lines:
remove_line(section, setting)
Expand All @@ -122,7 +135,7 @@ def remove_setting(section_name, setting)
# numbers for all of the sections *after* the one that
# was modified.
section_index = @section_names.index(section_name)
decrement_section_line_numbers(section_index + 1)
decrement_section_line_numbers(section_index + 1, existing_value.length)

return unless section.empty?
# By convention, it's time to remove this newly emptied out section
Expand Down Expand Up @@ -174,7 +187,9 @@ def save

# write new settings, if there are any
section.additional_settings.each_pair do |key, value|
fh.puts("#{@indent_char * (@indent_width || section.indentation || 0)}#{key}#{@key_val_separator}#{value}")
value.each do |v|
fh.puts("#{@indent_char * (@indent_width || section.indentation || 0)}#{key}#{@key_val_separator}#{v}")
end
end

if !whitespace_buffer.empty?
Expand Down Expand Up @@ -234,7 +249,7 @@ def read_section(name, start_line, line_iter)
return Section.new(name, start_line, end_line_num, settings, min_indentation)
end
if (match = @setting_regex.match(line))
settings[match[2]] = match[4]
(settings[match[2]] ||= []).push(match[4])
indentation = match[1].length
min_indentation = [indentation, min_indentation || indentation].min
end
Expand All @@ -245,16 +260,23 @@ def read_section(name, start_line, line_iter)
end

def update_line(section, setting, value)
(section.start_line..section.end_line).each do |line_num|
updated = false
section.end_line.downto section.start_line do |line_num|
next unless (match = @setting_regex.match(lines[line_num]))
if match[2] == setting
lines[line_num] = "#{match[1]}#{match[2]}#{match[3]}#{value}"
next unless match[2] == setting

lines.delete_at(line_num)
next if updated

value.each_with_index do |v, i|
lines.insert(line_num + i, "#{match[1]}#{match[2]}#{match[3]}#{v}")
end
updated = true
end
end

def remove_line(section, setting)
(section.start_line..section.end_line).each do |line_num|
section.end_line.downto section.start_line do |line_num|
next unless (match = @setting_regex.match(lines[line_num]))
if match[2] == setting
lines.delete_at(line_num)
Expand Down Expand Up @@ -307,26 +329,28 @@ def find_commented_setting(section, setting)
def insert_inline_setting_line(result, section, complete_setting)
line_num = result[:line_num]
s = complete_setting
lines.insert(line_num + 1, "#{@indent_char * (@indent_width || section.indentation || 0)}#{s[:setting]}#{s[:separator]}#{s[:value]}")
s[:value].each_with_index do |v, i|
lines.insert(line_num + 1 + i, "#{@indent_char * (@indent_width || section.indentation || 0)}#{s[:setting]}#{s[:separator]}#{v}")
end
end

# Utility method; given a section index (index into the @section_names
# array), decrement the start/end line numbers for that section and all
# all of the other sections that appear *after* the specified section.
def decrement_section_line_numbers(section_index)
def decrement_section_line_numbers(section_index, n = 1)
@section_names[section_index..(@section_names.length - 1)].each do |name|
section = @sections_hash[name]
section.decrement_line_nums
section.decrement_line_nums(n)
end
end

# Utility method; given a section index (index into the @section_names
# array), increment the start/end line numbers for that section and all
# all of the other sections that appear *after* the specified section.
def increment_section_line_numbers(section_index)
def increment_section_line_numbers(section_index, n = 1)
@section_names[section_index..(@section_names.length - 1)].each do |name|
section = @sections_hash[name]
section.increment_line_nums
section.increment_line_nums(n)
end
end

Expand Down
22 changes: 14 additions & 8 deletions lib/puppet/util/ini_file/section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,17 @@ def empty?
end

def update_existing_setting(setting_name, value)
existing_value = @existing_settings[setting_name]

@existing_settings[setting_name] = value

@end_line += value.length - existing_value.length
end

def remove_existing_setting(setting_name)
@end_line -= 1 if @existing_settings.delete(setting_name) && @end_line
existing_value = @existing_settings.delete(setting_name)

@end_line -= existing_value.length if existing_value && @end_line
end

# This is a hacky method; it's basically called when we need to insert
Expand All @@ -69,7 +75,7 @@ def remove_existing_setting(setting_name)
# of the lines.
def insert_inline_setting(setting_name, value)
@existing_settings[setting_name] = value
@end_line += 1 if @end_line
@end_line += value.length if @end_line
end

def set_additional_setting(setting_name, value)
Expand All @@ -79,17 +85,17 @@ def set_additional_setting(setting_name, value)
# Decrement the start and end line numbers for the section (if they are
# defined); this is intended to be called when a setting is removed
# from a section that comes before this section in the ini file.
def decrement_line_nums
@start_line -= 1 if @start_line
@end_line -= 1 if @end_line
def decrement_line_nums(n = 1)
@start_line -= n if @start_line
@end_line -= n if @end_line
end

# Increment the start and end line numbers for the section (if they are
# defined); this is intended to be called when an inline setting is added
# to a section that comes before this section in the ini file.
def increment_line_nums
@start_line += 1 if @start_line
@end_line += 1 if @end_line
def increment_line_nums(n = 1)
@start_line += n if @start_line
@end_line += n if @end_line
end
end
end
Loading