Re: Jinja2 syntax for conditionals (was: Re: Project options and other format enhancements (and dropping "variants"))



Replying again to the beginning of this Jinja2 subthread.


So I've presented what I think are valid cases against using a
predefined thing that is "not a DSL" and as such we do not control, the
problems with this are possibly not huge if we look at them more
closely - however - the *mere idea* of choosing a potentially more
arduous path in the name of a petty shed color has been driving me up
the wall as a matter of basic principle.


That said, I do *like* the fancy proposed light jinja-green for the
bike shed; and the more we discuss this, the more I think a vast
majority will prefer this kind of syntax (I might buy myself a lot of
hours in the future explaining to people that they should not be so
damn picky about trivial things, if I just give in now, too, that is
value in and of itself).


Seems this is the last sticking point of the proposal in general, and
if we all want to go python-ish then I'm prepared to give in; as long
as it can be guaranteed to *not be a programming language* (so no
multiple statements and the like are allowed in a condition, we should
not be able to abuse this).

Further, we have to make some concessions before hand about the options
that this code would be casing.

I suppose that if we impose the limitation that BuildStream can *never*
get deeply involved in the option declarations and their
meanings; cannot ever be allowed to understand the meaning of an
option, then the expressions and the nature of the variables tested in
those expressions become 100% in the domain of the user; if this is
guaranteed to always be the case, then not controlling the parser and
expressions is much less of a concern.

This *might* cause some issue if BuildStream wants to play smart aleck
and do freaky things one would expect it to, like automatically setting
some predefined well known built-in options; such as a "bst-arch"
option automatically defaulting to the hosts `uname -m` output.

Or, it might not cause any issue with things like the above, but if
rationally we can say that's where the madness stops, it looks like we
could live with this third party definition of our expressions format
situation.

The pythony expressions do look cuter; and maybe jinja2 is just so
nicely written that we can cleanly just yank the module we want out of
it and in-tree it like we're doing with fuse.

In any case; we have to close the book on this last week so the time to
act is yesterday.

Cheers,
    -Tristan

On Mon, 2017-09-18 at 16:11 +0100, Sam Thursfield wrote:
On 18/09/17 12:35, Sam Thursfield wrote:
What I'm suggesting is that we avoid creating a new DSL for expressions 
in the first place, we try and reuse an existing one instead. Ansible's 
use of Jinja proves that this is possible. I'm not entirely sure how it 
works though -- if I get time I will try and make a proof of concept 
expression parser and we can see if it can beat your 218 lines of code :-)

Attached is a proof of concept that demonstrates what I'm talking about. 
Also pasted here: https://pastebin.com/hmk0TPQj

It allows expressions that follow the Jinja2 expression syntax, as 
documented at: http://jinja.pocoo.org/docs/2.9/templates/#expressions

This supports arithmetic expressions (with infix syntax :-), compound 
conditionals like 'foo or (bar and baz)', string comparisons (case 
sensitive), list handling such as 'if "feature" in feature_list', all 
with a very Python-like syntax.

Some examples:

   9 + 5 == 14    (evaluates to True)
   "foo" in ["foo", "bar", "baz"]   (evaluates to True)

You can pass a dict of key->values into the evaluation function which 
become usable as variables within the condition expression. Booleans, 
integers, strings and lists are supported (and possibly more). For 
example if we pass "myvariable" set to the string "foo", we can use it 
like this:

   myvariable   (evaluates to True)
   myvariable == "boris"   (evaluates to False)
   myvariable[0] == "f"    (evaluates to True)

etc.

The whole thing is only 150 lines, and could be less if we didn't care 
about the "is defined" / "is undefined" operators (which require some 
special case hackery).

To make it work we just embed the condition expression into a template 
and then render it through jinja2 to get a result. Of course it feels a 
bit dirty, but Ansible has been doing this since 2012 to implement 
'when' conditions in playbooks and it seems to be working well enough 
for their tens of thousands of users.

Sam


_______________________________________________
Buildstream-list mailing list
Buildstream-list gnome org
https://mail.gnome.org/mailman/listinfo/buildstream-list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]