[augeas-devel] Default label for a node in a path expression

David Lutterkort lutter at watzmann.net
Mon Jan 6 22:04:52 UTC 2014


Hi Raphael,


On Fri, Dec 20, 2013 at 2:24 PM, Raphaël Pinson <
raphael.pinson at camptocamp.com> wrote:

> Hello,
>
>
> There's regularly people asking how to write idempotent set expressions.
> With labeled nodes, we have the usual trick:
>
>     set foo[.='bar'] 'bar'
>
> which creates the 'foo' node with the 'bar' value if it doesn't exist.
>

Yes, I agree with both - that it's not wel supported right now, and that it
is needed. The underlying problem is that there's no good way to infer from
a path expression where the newly created node  should go in case the path
expression doesn't match.

Rather than put something in the XPath language, I think it would be
cleaner to do this explicitly in a dedicated command. I can think of a few
ways to do that. The simplest would be a aug_set_or_create(expr, path,
value) that goes something like this:

if aug_match(expr) == 1
  aug_set(expr, value)
elsif aug_match(expr) == 0
  aug_set(path, value)
else
  complain
end

Here, EXPR is an XPath expression, and PATH is a literal path that has
enough information to create nodes from unambiguously. Maybe we'd need to
also allow a BASE (XPath expression) so that not all of PATH needs to be
fixed, and both EXPR and PATH would be relative to that.

But thinking of a scenario where you want to create an entry in /etc/hosts
if it's not there, that might still not be enough, and we might ultimately
need to introduce an 'if' statement into the language that aug_srun accepts
- though that has all kinds of ripple effects as you now also need to
define expressions for that if statement ...

So I've thought maybe we could add to the XPath language:
>
>     set /path/to/*[default() = "foo"][. = "bar"] "bar"
>
> If no node matching /path/to/* is found, then a new node would be created
> using label "foo". This would allow for multiple level defaults, such as:
>
>     set /path/to/*[default() = "foo"][. = "bar"]/*[default = "foz"][. =
> "baz"] "baz"
>
> and defaults would be applied at each level. I don't know about the
> feasability of this, but it would bring the most flexibility and it would
> allow to easily write idempotent set commands for seq nodes, too:
>
>     set /path/to/*[default() = "01"][. = "bar"] "bar"
>

I think that's an elegant approach, though I am not sure how understandable
this would be to users. At the very least, I'd use a different syntax than
the '[ ... ]' predicates (right now '=' means comparison, not assignment),
something like

set /path/to/*<01>[. = "bar"]

That will lead to headaches in parse_name in pathx.c, since we will then
disallow '{' in file names. Maybe

set /path/to/*[<01> . = "bar"]

would reduce the need to restrict what characters we like in file names ...

David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20140106/6f2d8766/attachment.htm>


More information about the augeas-devel mailing list