Clear all existing record definitions. Only used for testing.
# File lib/puppet/util/fileparsing.rb, line 125 def clear_records @record_types.clear @record_order.clear end
# File lib/puppet/util/fileparsing.rb, line 130 def fields(type) if record = record_type(type) record.fields.dup else nil end end
Try to match a record.
# File lib/puppet/util/fileparsing.rb, line 144 def handle_record_line(line, record) ret = nil if record.respond_to?(:process) if ret = record.send(:process, line.dup) unless ret.is_a?(Hash) raise Puppet::DevError, "Process record type #{record.name} returned non-hash" end else return nil end elsif regex = record.match # In this case, we try to match the whole line and then use the # match captures to get our fields. if match = regex.match(line) fields = [] ret = {} record.fields.zip(match.captures).each do |field, value| if value == record.absent ret[field] = :absent else ret[field] = value end end else nil end else ret = {} sep = record.separator # String "helpfully" replaces ' ' with /\s+/ in splitting, so we # have to work around it. if sep == " " sep = / / end line_fields = line.split(sep) record.fields.each do |param| value = line_fields.shift if value and value != record.absent ret[param] = value else ret[param] = :absent end end if record.rollup and ! line_fields.empty? last_field = record.fields[-1] val = ([ret[last_field]] + line_fields).join(record.joiner) ret[last_field] = val end end if ret ret[:record_type] = record.name return ret else return nil end end
Try to match a specific text line.
# File lib/puppet/util/fileparsing.rb, line 139 def handle_text_line(line, record) line =~ record.match ? {:record_type => record.name, :line => line} : nil end
# File lib/puppet/util/fileparsing.rb, line 205 def line_separator @line_separator ||= "\n" @line_separator end
Split text into separate lines using the record separator.
# File lib/puppet/util/fileparsing.rb, line 212 def lines(text) # Remove any trailing separators, and then split based on them # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com] x = text.sub(/#{self.line_separator}\Q/,'').split(self.line_separator) end
Split a bunch of text into lines and then parse them individually.
# File lib/puppet/util/fileparsing.rb, line 219 def parse(text) count = 1 lines(text).collect do |line| count += 1 if val = parse_line(line) val else error = Puppet::ResourceError.new("Could not parse line #{line.inspect}") error.line = count raise error end end end
Handle parsing a single line.
# File lib/puppet/util/fileparsing.rb, line 234 def parse_line(line) raise Puppet::DevError, "No record types defined; cannot parse lines" unless records? @record_order.each do |record| # These are basically either text or record lines. method = "handle_#{record.type}_line" if respond_to?(method) if result = send(method, line, record) record.send(:post_parse, result) if record.respond_to?(:post_parse) return result end else raise Puppet::DevError, "Somehow got invalid line type #{record.type}" end end nil end
Define a new type of record. These lines get split into hashes. Valid options are:
:absent: What to use as value within a line, when a field is
absent. Note that in the record object, the literal :absent symbol is
used, and not this value. Defaults to "".
:fields: The list of fields, as an array. By default, all
fields are considered required.
:joiner: How to join fields together. Defaults to 't'.
:optional: Which fields are optional. If these are missing,
you'll just get the 'absent' value instead of an ArgumentError.
:rts: Whether to remove trailing whitespace. Defaults to
false. If true, whitespace will be removed; if a regex, then whatever
matches the regex will be removed.
:separator: The record separator. Defaults to /s+/.
# File lib/puppet/util/fileparsing.rb, line 268 def record_line(name, options, &block) raise ArgumentError, "Must include a list of fields" unless options.include?(:fields) record = FileRecord.new(:record, options, &block) record.name = name.intern new_line_type(record) end
Are there any record types defined?
# File lib/puppet/util/fileparsing.rb, line 278 def records? defined?(@record_types) and ! @record_types.empty? end
Define a new type of text record.
# File lib/puppet/util/fileparsing.rb, line 283 def text_line(name, options, &block) raise ArgumentError, "You must provide a :match regex for text lines" unless options.include?(:match) record = FileRecord.new(:text, options, &block) record.name = name.intern new_line_type(record) end
Generate a file from a bunch of hash records.
# File lib/puppet/util/fileparsing.rb, line 293 def to_file(records) text = records.collect { |record| to_line(record) }.join(line_separator) text += line_separator if trailing_separator text end
Convert our parsed record into a text record.
# File lib/puppet/util/fileparsing.rb, line 302 def to_line(details) unless record = record_type(details[:record_type]) raise ArgumentError, "Invalid record type #{details[:record_type].inspect}" end if record.respond_to?(:pre_gen) details = details.dup record.send(:pre_gen, details) end case record.type when :text; return details[:line] else return record.to_line(details) if record.respond_to?(:to_line) line = record.join(details) if regex = record.rts # If they say true, then use whitespace; else, use their regex. if regex == true regex = /\s+$/ end return line.sub(regex,'') else return line end end end
Whether to add a trailing separator to the file. Defaults to true
# File lib/puppet/util/fileparsing.rb, line 332 def trailing_separator if defined?(@trailing_separator) return @trailing_separator else return true end end
# File lib/puppet/util/fileparsing.rb, line 340 def valid_attr?(type, attr) type = type.intern if record = record_type(type) and record.fields.include?(attr.intern) return true else if attr.intern == :ensure return true else false end end end