[augeas-devel] ConfigObj: working lens seeking tips/improvements

Mol, Xavier (SCC) xavier.mol at kit.edu
Tue Nov 3 10:36:15 UTC 2015


Hi Yclept,

 

do I understand your lens correctly in that you try to find commented records, which are the same as regular records, just that they happen to be preceeded by a comment sign ('#')? Of course, that is your choice, but do you gain much out of that? Once you have found a comment sign, you may simply store all of the following up to the end of the line as value. In fact, that's what Util.comment does. And in case a record is suffixed by a comment, Util.comment_eol exists and creates a different node in the tree to represent that.

 

Here is a draft for possible simplifications:

 

module ConfigObj_Simple =

  let sp = Sep.space

  let empty = Util.empty

  let comment = Util.comment

 

  let record =

    let option = key /[a-z_]+/ in

    let value_all = Quote.dquote_spaces in

    [ Util.indent . option . del /[ \t]*=/ " =" . (sp . value_all)? . Util.comment_or_eol ]

 

  let lns = ( empty | comment | record )*

 

 

I'm sorry, this example module doesn't even pass the tests from augparse (ambiguity with Quote.dquote_spaces and trailing comments and after that still the very same issue as discussed in the parallel mail thread), so it is more or less again a demonstration on how one can reuse what is already present in Augeas' shipped modules. Also, I made some compromises. For example, I allow "[a-z_]+" as a valid string for option, whereas you forbid '_' as first and last character. Yes, this might allow for wrong configuration files to be created with Augeas, but in my personal opinion, Augeas makes it too difficult to enforce all the details that might go into creating a syntactically correct configuration file for every theoretically possible situation. So what I normally do is allow for a different syntax, that achieves the same result. In the case of trailing comments that means, that they are not supported by my modules – comments always have to be on their own line by themselves, which effectively doesn't alter the meaning of the configuration and saves me a lot of headache. I also require all lines to have an end-of-line character, since I have not found a way of matching the end of a file otherwise.

 

So in short, if it seems to be impossible to match all you want, try cut it down to things you need at its core and make compromises. ;-) Augeas is not as powerful as any scripting or programming language and therefore some configuration files might be actually impossible to be parsed with it (though I haven't found an example for that yet).

 

Ciao,

Xavier.

 

 

 

From: Yclept Nemo [mailto:orbisvicis at gmail.com] 
Sent: Monday, November 02, 2015 5:57 PM
To: Mol, Xavier (SCC)
Cc: augeas-devel
Subject: Re: [augeas-devel] ConfigObj: working lens seeking tips/improvements

 

Hi,

> I'm sorry to say that, but personally, I have too little time to learn your lens to the same level as you know it

That's no-problem/understandable, for others I've substituted the ConfigObj_Simple module with generic constructs.

> I can only repeat a tip from the parallel mail thread: Use variables and constructs from the generic Augeas modules like Rx, Util, Sep and Build.
> Hence they are very refined and allow people foreign to your code a quick start

Here is the ConfigObj_Simple module with as much as possible substituted with generic module constructs. There really isn't much simplification possible due to the differing definitions of both comments (module Util) and quotes (module Quote):

(* ConfigObj_Simple lens:
   Pro:
    * removes extraneous nodes "type" and "commented = false"
    * fast
   Con:
    * returns raw values - stripping surrounding quotes from value_qstring creates overlapping lenses in union.put
    * does not validate value types internally
    * child nodes of record are still order-dependent: "commented" before ".comment"
*)

module ConfigObj_Simple =
    let spaces              = Util.del_opt_ws " "
    let newline             = Util.del_str "\n"
    let option              = key /[a-z]([a-z_]*[a-z])?/
    let value_all           = store (/"([^\n\"]*([\].)*)*"/ | /[^ \t\n"#][^ \t\n#]*/)
    let sep_comment         = Util.del_str "#"
    let comment_label       = label ".comment"
    let record_commented    = [ sep_comment . spaces . label "commented" ]
    let record_comment      = [ comment_label . sep_comment . store /.*/ ]
    let record_simple       = option . spaces . Sep.equal . (spaces . value_all)? . (Sep.opt_space | (spaces . record_comment))
    let record              = [ record_commented? . record_simple ]
    let comment             = [ comment_label . sep_comment . store (/.*/ - (/[ \t]*/ . lens_ctype record_simple)) ]
    let entry               = Util.indent . ( record | comment ) . newline
    let empty               = [ Util.eol ]
    let line                = empty | entry
    let lns                 = line *

> Besides that, the generic Build module provides functions, that show you, how you could combine lenses with no strict ordering or existence: http://augeas.net/docs/references/lenses/files/build-aug.html#Build.COMBINATORICS.

That is a good idea but doesn't help in situtations such as ConfigObj_Simple or (simplified):

module AmbiguousCombinatorics =
    let a   = store /a/ . [ label ".comment" ]
    let b   = [ label "commented" ]
    let c   = [ Build.combine_two a b ]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20151103/64b39efe/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6401 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20151103/64b39efe/attachment.p7s>


More information about the augeas-devel mailing list