Ciaran McCreesh wrote:
> On Mon, 31 Aug 2009 20:15:37 +0200
> Mounir Lamouri <volk...@gentoo.org> wrote:
>   
>>> * at least one of a b c, possibly only if d
>>>   
>>>       
>> IUSE_REQUIREMENTS="d? ( || ( a b c ) )"
>>     
>
> Moderately eww...
>
>   
>>> * exactly one of a b c, possibly only if d
>>>   
>>>       
>> IUSE_REQUIREMENTS="d? ( || ( a b c ) ) a ? ( -b -c ) b ? ( -a -c ) c?
>> ( -a -b )"
>>     
>
> Really eww...
>
>   
>>> * at most one of a b c, possibly only if d
>>>   
>>>       
>> IUSE_REQUIREMENTS="d? ( a? ( -b -c) b? ( -a -c ) c? ( -a -b) )"
>>     
>
> Similarly eww.
>
>   
>>> From a package manager perspective, it's much easier to give good
>>> advice to the user if we're told by the ebuild exactly what's going
>>> on. 
>>>       
>> So I think we can satisfy all use cases with the classic Gentoo syntax
>> even if new operators could be appreciated ;)
>>     
>
> How do we translate the above into nice friendly messages for the user?
> Taking the "exactly one" case, it's much better to say to the user:
>
>     * If 'd' is enabled, exactly one of 'a', 'b' or 'c' must be enabled
>
> Than:
>
>     * If 'd' is enabled, at least one of 'a', 'b' or 'bc' must be
>       enabled
>
> Then when the user turns on all three:
>
>     * If 'd' is enabled, if 'a' is enabled, 'b' must not be enabled
>     * If 'd' is enabled, if 'a' is enabled, 'c' must not be enabled
>     * If 'd' is enabled, if 'b' is enabled, 'a' must not be enabled
>     * If 'd' is enabled, if 'b' is enabled, 'c' must not be enabled
>     * If 'd' is enabled, if 'c' is enabled, 'a' must not be enabled
>     * If 'd' is enabled, if 'c' is enabled, 'b' must not be enabled
>
> And in the general case, there's no way of translating the latter into
> the former.
>
> Much easier for everyone if you just say what you mean rather than
> converting it into some convoluted (but theoretically equivalent) less
> expressive syntax.
>   
We don't see this feature the same way. I don't want to add a feature
that will prevent the maintainer to die if we can't found another way. I
want the package manager do make some decisions before calling the ebuild.

For example:
* if a then b
IUSE_REQUIREMENTS="a? ( b )"
if USE="-a b" is used, the package manager should enable a because it's
needed for b and it should show this. We could say we also can disable b
but we can't know if a USE flag is disabled or just not enabled (in
other words, because every USE flags is disabled by default). In
addition, we can consider if someone want to enable a feature it should
be more important than disabling another.

* if a then not b
IUSE_REQUIREMENTS="a? ( -b )"
if USE="a b", b should be disabled by the PM. It's up to the maintainer
to choose a default behavior by setting the relation between USE flags
(b? ( -a ) is equivalent but will disable a).

* at least one of a b c, possibly only if d
IUSE_REQUIREMENTS="d? ( || ( a b c ) )"
if USE="d", the PM will enable a.

* exactly one of a b c, possibly only if d
IUSE_REQUIREMENTS="d? ( || ( a b c ) ) a? ( -b -c ) b? ( -a -c ) c? ( -a
-b )"
if USE="d", same as before.
if USE="d a", nothing
if USE="d a b", it's harder because a? ( -b -c ) and b? ( -a -c ). We
can imagine to disable b because a is the first value in || ( a b c )
but it's not satisfying. We can imagine another operator like | to
represent this dependency: "d? ( | ( a b c ) )"

* at most one of a b c, possibly only if d
IUSE_REQUIREMENTS="d? ( a? ( -b -c) b? ( -a -c ) c? ( -a -b) )"
it's quite similar to the previous one but here it's harder to guess
which one should be keep if USE="d a b".
As previously, we can imagine another operator like "d? ( ||| ( a b c ) )"

But if we want to move to a really generic specification, we can
introduce something similar to Exherbos syntax:
exactly-N, max-N, min-N with N as a positive integer.
So, we could write:
"d? ( exactly-1? ( a b c ) )"
"d? ( max-1? ( a b c ) )"
"d? ( min-1? ( a b c ) )"
With this syntax, it's easy to consider first values as one to use by
default for the PM (so, never failing).

The only big issue I see with this syntax is it will make exactly-N,
max-N and min-N no valid USE flags. But we can prevent that by prefixing
the name by an illegal character like ||exactly-1.

About the dying thing, I just want to precise I don't want to add a
feature that will only die with a cool message. Maintainers can do that.
The idea is to prevent maintainers to do that without silently enabling
a feature or moving to an unstable state (because of EAPI-2 use
dependencies).
It will let maintainers to die if they want. They will not have to set
"a? ( b )" if they really think a shouldn't be enabled (even with
possible user knowledge) if b is enabled. In this case, the classic die
statement will be ok.

Thanks,
Mounir

Reply via email to