Re: Project options and other format enhancements (and dropping "variants")



Thanks for the quick response!

On (1) Building particular elements for debugging, when you say this:

Enabling or disabling options for a specific element only is tricky; because
it's also very important to be able to express option conditionals in
project.conf (because you want to make sweeping statements which optionally
apply to the whole project as well).

I think you're saying that 'bst build --option mylib.bst:debug=true' is overly
simplistic, because there may be other things listening for 'debug=true' in
project.conf that would affect things on a global level.

In other words, setting 'debug=true' for just mylib.bst may make it
incompatible with the rest of it's pipeline.

Does that sound right? If not then the rest of this reply might not be as
relevant.

(?):
condition: (contains debug_elements "mylib.bst")
value:
random-key: The value I would apply if mylib is on the debug list

Just to make sure we're thinking the same thing with this example, here's my
attempt to expand it more:

    project.conf:
    ...
    variables:
    - '??':
        condition: (ifeq 'debug' 'on')
        value:
          debug-flags: --enable-debug
    - '??':
        condition: (and (ifeq 'debug' 'off') (nonempty debug_elements))
        value:
          some-key: Important thing to do because of mixed debug / non-debug.
    ...

    mylib.bst:
    ...
    '??':
      condition: (or (ifeq 'debug' 'on') (contains debug_elements "mylib.bst"))
      value:
        random-key: The value I would apply if mylib is on the debug list
    ...

Then at the command-line, something like:

    bst build --option debug_elements=mylib.bst

Maybe even appending to the list / inserting into the set:

    bst build --option debug_elements+=mylib.bst

If my understanding is correct, I feel I need to make some more examples before
I can agree that the 'inconsistent value of "debug"' thing is unsupportable.

I think the help the .bst and project.conf authors would need from the
BuildStream format would be along the lines of advertising what is supported
and asserting that unsupported things aren't used. This seems possible if
there's some namespacing of options, e.g. introducing 'this.debug' and
'global.debug' in elements (not fully baked yet :).

On (2) Allowing elements to be more specific:

Yes, this is really what I like so much about variants.

The problems I have with moving forward for a full blown variant
solution with competing orthogonal variants, are mostly that:

o It's going to be very, very tricky to implement.

We already have an imperfect algorithm for resolving variants when
there can only be one variant per element. The solution which works
exactly to spec takes several minutes to solve (so already we need
work to get it right with a proper constraint solving algorithm or
engine, which still wont work in linear time but should be usable).

o While it may be easy enough to explain the rules of constraint
resolution to the user, it will often be difficult for the user
to easily predict what variant of what element will be chosen.

Now that I've read the tricky.bst[1] test case for variants, I realise they do
much more than I thought. Automatic resolution is cool, I like the maximum
ambivalence. I see what you mean that it leads to implementation difficulty and
sometimes user confusion.

I think they'd still be very usable without automatic resolution. Maybe I need
to read more of those test cases :)

In the case of tricky.bst, as a user I'd be happy with getting an error message
for that and resolving the conflict myself. I'd be ok with fixing tricky.bst to
depend on the second variant of tricky-first, adding a comment as to why it's
there so it might go away if tricky-first changes. If we added some sort of
semantic tag in the comment about the resolution, then we might be able to
automate some of that outside of BuildStream.

e.g.

    tricky.bst:
    ...
    depends:
      - filename: tricky-first.bst
        variant: second  #!resolves: tricky-second.bst:second
      - filename: tricky-second.bst
        variant: second

However, what we dont have is the element declaring the value of an option on
an element it depends on; depending on how the element itself was configured;
this all leads back down the variant path where an agreement between elements
must be reached.

When you say this about options in project.conf, I think something similar
about options in elements for large projects:

These options should have some metadata which can be used to declare the
defaults, assert valid values of the options, and also a description string
which the CLI can use to communicate the meaning of project options to
buildstream users (not all users building a project wrote the project.conf).

It feels like in addition to the top-level choices of project.conf and the CLI,
elements could encapsulate some config complexity and provide an interface to
things that depend on them. I think that's another thing that draws me (and I'm
guessing you) to variants.

Here is a similar example to the one I brought for my 'point (2)' before, now
a bit fuller:

    app.bst:
    ...
    depends:
      - lib1.bst
      - filename: lib2.bst
        variants: flying-ponies
    ...

    lib1.bst:
    ...
    depends:
      - filename: lib2.bst
        variants: dancing-badgers
    ...

    lib2.bst:
    ...
    variants:
      - name: flying-ponies
      - name: dancing-badgers
        description: Summons a clan of gyrating badgers for a short
                     period. The top speed of a badger is 30km/h, fact.
    variables:
    - conf-extra:
      '??':
        - condition: (ifvariant "flying-ponies")
          value: --enable-flying-ponies
        - condition: (ifvariant "dancing-badgers")
          value: --enable-dancing-badgers
        - condition: >-
            (and
              (ifvariant "dancing-badgers")
              (ifvariant "flying-ponies"))
          value: --enable-flying-ponies --enable-dancing-badgers
    ...

If the ponies / badgers combo is no good then we can do:

    lib2.bst:
    ...
    variables:
    - conf-extra:
      '??':
        - condition: (ifvariant "flying-ponies")
          value: --enable-flying-ponies
        - condition: (ifvariant "dancing-badgers")
          value: --enable-dancing-badgers
        - condition: >-
            (and
              (ifvariant "dancing-badgers")
              (ifvariant "flying-ponies"))
          value: '!!': Sorry, it's badgers or ponies, not both.
    ...

Some criticism of my own example:

- You can see I've mangled the syntax of variants in with conditions, I'm not
  very attached to my choices there, it's more to show that it's not a big step
  away from your proposal. It also shows it doesn't need automatic constraint
  resolution, it's all explicit.

- Even with only two variants (they could have been options), I can see it is
  harder to read. I at least need to factor in architecture, debug, etc. too.

- It's a contrived example, I need to relate it back to actual problems I have
  in the BuildStream adoption POC I'm working on.

I'm torn, of course I wish variants was going to work perfectly. On the other
hand I have to concede that the implicit nature of how things resolved was
already a little bit complex for the user to digest, and increasing that
complexity by making them orthogonal (both to implement and to use) seems to
be unwise.

Would you consider dropping the automatic resolution, or is that maybe one of
the main attractions for you?

Maybe there is a practical way forward without closing the door entirely on
the variants approach.

I really hope so too, it feels like config isn't yet solved enough to set the
direction for all time. I also think it's a critical piece for my own adoption
of BuildStream.

Cheers!
Angelos

P.S. This is my first time using a mailing list, please let me know if there's
any netiquette I'm not following. If I'm off-key in any way, please assume it's
because I'm learning :)

[1] https://gitlab.com/BuildStream/buildstream/blob/master/tests/loader/variants/elements/tricky.bst


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