On Tue, Aug 23, 2011 at 10:32:54AM -0400, David Kavanagh wrote:
> I did get this working. In a nutshell, I modified to_line like this;
>   def self.to_line(hash)
>     return super unless hash[:record_type] == :parsed
>     "#{hash[:name]}=#{hash[:value]}"
>   end

As I said, I wouldn't to that. Just pass a :to_line => proc {...} to your
record_line call because you will then just overwrite the to_line method
of that particular record_type.

> 
> which handles the other line types. To handle wrapping values in
> quotes, I changed the type like this;
>   newproperty(:value) do
>     munge do |value|
>       '"'+value.to_s+'"'
>     end
>     newvalues(/^\S+$/)
>   end
> 
> so, that line where value.to_s is wrapped with quotes seems to work nicely.

Hm, in my opinion using a regex that gets the value as an unqoted string
and put the quotes back to the string in the to_line method looks saner
than munging the value.

> 
> My other problem now is that aside from handling these variations
> 
> # comment lines
> key="value"
> 
> I also need to handle this;
> 
> key="value" #optional comment
> 
> I could add to the regex for the line matching (in record_line
> :parsed). Then, I'm not sure how to get that into to_line for output.

You have to store the inlinecomment in the record hash and then put it
back in the to_line hook. So this should work
(to test the regex I recommend rubular.com)

record_line :parsed,
  :fields   => %w{name value comment},
  :optional => %w{value comment},
  :regex    => /^\s*(.*?)(?:\s*=\s*(.*?))?(?:\s*#\s*(.*))?\s*$/,
  :to_line  => proc { |hash|
    str = hash[:name]
    str += "=\"#{hash[:value]}\"" if hash[:value] != :absent
    str += " # #{hash[:comment]}" if hash[:comment] != :absent
    str
  }


> 
> David
> 
> On Mon, Aug 22, 2011 at 8:48 PM, David Kavanagh <dkavan...@gmail.com> wrote:
> > Thanks, I'll try to work through your suggestions. I took this from
> > the nova_config stuff on github, so that was my example.
> >
> > David
> >
> > On Mon, Aug 22, 2011 at 7:36 PM, Stefan Schulte
> > <stefan.schu...@taunusstein.net> wrote:
> >> On Mon, Aug 22, 2011 at 06:33:27PM -0400, David Kavanagh wrote:
> >>> I'm working on a type/provider for the eucalyptus.conf file. What I
> >>> have generally works for modifying properties. I have a couple of
> >>> issues and not being very experienced with Ruby and custom providers,
> >>> I wonder if anyone can help?
> >>> The code is included below. The key/value constructs in the file look 
> >>> like:
> >>>
> >>> key="value"
> >>>
> >>> 1. I'm not getting the quotes surrounding the value, which I think I
> >>> can figure out myself.
> >>> 2. I get all blanks and comments replaced by "=", which is more of a 
> >>> problem.
> >>>
> >>> David
> >>>
> >>>
> >>> require 'puppet/provider/parsedfile'
> >>>
> >>> eucaconf = "/etc/eucalyptus/eucalyptus.conf"
> >>>
> >>> Puppet::Type.type(:eucalyptus_config).provide(
> >>>   :parsed,
> >>>   :parent => Puppet::Provider::ParsedFile,
> >>>   :default_target => eucaconf,
> >>>   :filetype => :flat
> >>> ) do
> >>>
> >>>   confine :exists => eucaconf
> >>>   text_line :comment, :match => /^#/;
> >>>   text_line :blank, :match => /^\s*$/;
> >>>
> >>>   record_line :parsed,
> >>>     :fields => %w{line},
> >>>     :match => /(.*)/ ,
> >>>     :post_parse => proc { |hash|
> >>>       Puppet.debug("eucalyptus config line:#{hash[:line]} has been 
> >>> parsed")
> >>>       if hash[:line] =~ /^\s*(\S+)\s*=\s*(\S+)\s*$/
> >>>         hash[:name]=$1
> >>>         hash[:value]=$2
> >>>       elsif hash[:line] =~ /^\s*(\S+)\s*$/
> >>>         hash[:name]=$1
> >>>         hash[:value]=false
> >>>       else
> >>>         raise Puppet::Error, "Invalid line: #{hash[:line]}"
> >>>       end
> >>>     }
> >>
> >> instead of the post_parse hook you can probably just change your regex
> >>  :fields   => %w{name value},
> >>  :optional => %w{value},
> >>  :match    => /^\s*(.*?)(?:\s*=\s*"(\S+)")?\s*$/
> >>
> >> This matches line like
> >>
> >>  foo
> >>
> >> and
> >>
> >>  foo = "bar"
> >>
> >>>
> >>>   def self.to_line(hash)
> >>>     "#{hash[:name]}=#{hash[:value]}"
> >>>   end
> >>
> >> If you just overwrite the to_line method you have to take care of the
> >> different record_types (you defined :comment, :text and :parsed).
> >> So you have to do
> >>
> >>    def self.to_line(hash)
> >>      return super unless hash[:record_type] == :parsed
> >>      if hash[:value] == :absent
> >>        hash[:name]
> >>      else
> >>        "#{hash[:name]}=\"#{hash[:value]}\""
> >>      end
> >>    end
> >>
> >> Nevertheless the "right" thing to do is to pass a block to the
> >> record_line method:
> >>
> >>  record_line :parsed,
> >>    :fields  => ...,
> >>    :match   => ...,
> >>    :to_line => proc { |hash|
> >>      if hash[:value] == :absent
> >>        hash[:name]
> >>      else
> >>        "#{hash[:name]}=\"#{hash[:value]}\""
> >>      end
> >>    }
> >>
> >> Hope that helps.
> >>
> >> -Stefan
> >>
> >
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Puppet Users" group.
> To post to this group, send email to puppet-users@googlegroups.com.
> To unsubscribe from this group, send email to 
> puppet-users+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/puppet-users?hl=en.
> 

Attachment: pgpH9X2rIXtih.pgp
Description: PGP signature

Reply via email to