You could also make a larger use of common modules (Util, Rx, Sep, Build) to simply the lens. Here is my take for the lens:<br><br><br>module Gmetad =<br> <br>autoload xfm<br><br>let quoted =<br> let quote = Util.del_str "\""<br>
in quote . store Rx.word. quote<br> <br>let data_source =<br> let host = [ label "host" . store Rx.word ]<br> in Build.key_value_line "data_source" Sep.space<br> (quoted . Sep.space<br> . Build.opt_list host Sep.space)<br>
<br> <br>let gridname = Build.key_value_line "gridname" Sep.space quoted <br><br>let lns = (gridname | data_source | Util.empty)*<br><br>let filter = incl "/etc/gmetad.conf"<br>let xfm = transform lns filter<br>
<br><br><br><br>and for the test file:<br><br>module Test_gmetad =<br> let conf = "gridname \"grid\"<br>data_source \"group_name\" ds1 ds2 <a href="http://ds3.example.com">ds3.example.com</a><br>
data_source \"group_other\" www1 www2 <a href="http://www3.example.com">www3.example.com</a><br>"<br> test Gmetad.lns get conf =<br> { "gridname" = "grid" }<br> { "data_source" = "group_name"<br>
{ "host" = "ds1" }<br> { "host" = "ds2" }<br> { "host" = "<a href="http://ds3.example.com">ds3.example.com</a>" } }<br> { "data_source" = "group_other"<br>
{ "host" = "www1" }<br> { "host" = "www2" }<br> { "host" = "<a href="http://www3.example.com">www3.example.com</a>" } }<br><br><br><br>Raphaël<br><br>
<br><br><div class="gmail_quote">On Thu, May 31, 2012 at 4:57 PM, Raphaël Pinson <span dir="ltr"><<a href="mailto:raphael.pinson@camptocamp.com" target="_blank">raphael.pinson@camptocamp.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br><div class="gmail_quote"><div><div class="h5">On Thu, May 31, 2012 at 4:38 PM, Nathaniel Cook <span dir="ltr"><<a href="mailto:nvcook42@gmail.com" target="_blank">nvcook42@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I have been working on writing a simplified lens for the ganglia<br>
gmetad.conf file. I have the lens working as I like but when I try to<br>
use augeas to add entries to the file I get errors on save if the file<br>
doesn't exist or is empty. It says it cannot parse the entire input:<br>
<br>
/augeas/files/etc/gmetad.conf/error = "parse_failed"<br>
/augeas/files/etc/gmetad.conf/error/pos = "0"<br>
/augeas/files/etc/gmetad.conf/error/line = "1"<br>
/augeas/files/etc/gmetad.conf/error/char = "0"<br>
/augeas/files/etc/gmetad.conf/error/lens =<br>
"/usr/share/augeas/lenses/gmetad.aug:22.12-.56:"<br>
/augeas/files/etc/gmetad.conf/error/message = "Get did not match entire input"<br>
<br>
<br>
Here is the lens:<br>
<br>
<br>
module Gmetad =<br>
autoload xfm<br>
<br>
let quote = Util.del_str "\""<br>
let space = del /[ \t]+/ " "<br>
let eol = Util.del_str "\n"<br>
let empty = del /[ \t]*/ "" . eol<br>
<br>
let host = store /[a-zA-Z0-9._]+/<br>
let hosts = ( space . [ seq "hosts" . host ] )+<br>
let group = [ label "group" . quote . store /[a-zA-Z0-9._ ]+/ . quote ]<br>
let data_source = [ counter "hosts" . label "data_source" .<br>
Util.del_str "data_source" . space . group . [ label "hosts" . hosts ]<br>
]<br>
<br>
let gridname = [ label "gridname" . Util.del_str "gridname" .<br>
space . quote . store /[a-zA-Z0-9._]+/ . quote ]<br>
<br>
let lns = (gridname . empty)* . (data_source . empty)*<br>
<br>
let filter = incl "/etc/gmetad.conf"<br>
let xfm = transform lns filter<br>
<br>
<br>
Here is the test module:<br>
<br>
module Test_gmetad =<br>
let conf = "gridname \"grid\"<br>
data_source \"group_name\" ds1 ds2 <a href="http://ds3.example.com" target="_blank">ds3.example.com</a><br>
data_source \"group_other\" www1 www2 <a href="http://www3.example.com" target="_blank">www3.example.com</a><br>
"<br>
test Gmetad.lns get conf =<br>
{ "gridname" = "grid" }<br>
{ "data_source"<br>
{ "group" = "group_name" }<br>
{ "hosts"<br>
{ "1" = "ds1" }<br>
{ "2" = "ds2" }<br>
{ "3" = "<a href="http://ds3.example.com" target="_blank">ds3.example.com</a>" }<br>
}<br>
}<br>
{ "data_source"<br>
{ "group" = "group_other" }<br>
{ "hosts"<br>
{ "1" = "www1" }<br>
{ "2" = "www2" }<br>
{ "3" = "<a href="http://www3.example.com" target="_blank">www3.example.com</a>" }<br>
}<br>
}<br>
<br>
let empty = ""<br>
<br>
test Gmetad.lns get empty = ?<br>
<br></blockquote></div></div><div><br><br>An empty (or non existent) file is not an empty string, but a single carriage return. The test should thus be:<br><br>test Gmetad.lns get "\n" = ?<br><br>which fails since the lens cannot parse a single carriage return. This is the reason why it fails in augtool.<br>
<br><br>Doesn't this format not support empty lines? If it does, I'd advise to use Util.eol in gridname and data_source, and write lns as:<br><br>let lns = (gridname | data_source | Util.empty)*<br><br>or does the order strictly matter?<span class="HOEnZb"><font color="#888888"><br>
<br><br>Raphaël<br></font></span></div></div><br>
</blockquote></div><br>