1 |
Ciaran McCreesh wrote: |
2 |
> On Mon, 31 Aug 2009 20:15:37 +0200 |
3 |
> Mounir Lamouri <volkmar@g.o> wrote: |
4 |
> |
5 |
>>> * at least one of a b c, possibly only if d |
6 |
>>> |
7 |
>>> |
8 |
>> IUSE_REQUIREMENTS="d? ( || ( a b c ) )" |
9 |
>> |
10 |
> |
11 |
> Moderately eww... |
12 |
> |
13 |
> |
14 |
>>> * exactly one of a b c, possibly only if d |
15 |
>>> |
16 |
>>> |
17 |
>> IUSE_REQUIREMENTS="d? ( || ( a b c ) ) a ? ( -b -c ) b ? ( -a -c ) c? |
18 |
>> ( -a -b )" |
19 |
>> |
20 |
> |
21 |
> Really eww... |
22 |
> |
23 |
> |
24 |
>>> * at most one of a b c, possibly only if d |
25 |
>>> |
26 |
>>> |
27 |
>> IUSE_REQUIREMENTS="d? ( a? ( -b -c) b? ( -a -c ) c? ( -a -b) )" |
28 |
>> |
29 |
> |
30 |
> Similarly eww. |
31 |
> |
32 |
> |
33 |
>>> From a package manager perspective, it's much easier to give good |
34 |
>>> advice to the user if we're told by the ebuild exactly what's going |
35 |
>>> on. |
36 |
>>> |
37 |
>> So I think we can satisfy all use cases with the classic Gentoo syntax |
38 |
>> even if new operators could be appreciated ;) |
39 |
>> |
40 |
> |
41 |
> How do we translate the above into nice friendly messages for the user? |
42 |
> Taking the "exactly one" case, it's much better to say to the user: |
43 |
> |
44 |
> * If 'd' is enabled, exactly one of 'a', 'b' or 'c' must be enabled |
45 |
> |
46 |
> Than: |
47 |
> |
48 |
> * If 'd' is enabled, at least one of 'a', 'b' or 'bc' must be |
49 |
> enabled |
50 |
> |
51 |
> Then when the user turns on all three: |
52 |
> |
53 |
> * If 'd' is enabled, if 'a' is enabled, 'b' must not be enabled |
54 |
> * If 'd' is enabled, if 'a' is enabled, 'c' must not be enabled |
55 |
> * If 'd' is enabled, if 'b' is enabled, 'a' must not be enabled |
56 |
> * If 'd' is enabled, if 'b' is enabled, 'c' must not be enabled |
57 |
> * If 'd' is enabled, if 'c' is enabled, 'a' must not be enabled |
58 |
> * If 'd' is enabled, if 'c' is enabled, 'b' must not be enabled |
59 |
> |
60 |
> And in the general case, there's no way of translating the latter into |
61 |
> the former. |
62 |
> |
63 |
> Much easier for everyone if you just say what you mean rather than |
64 |
> converting it into some convoluted (but theoretically equivalent) less |
65 |
> expressive syntax. |
66 |
> |
67 |
We don't see this feature the same way. I don't want to add a feature |
68 |
that will prevent the maintainer to die if we can't found another way. I |
69 |
want the package manager do make some decisions before calling the ebuild. |
70 |
|
71 |
For example: |
72 |
* if a then b |
73 |
IUSE_REQUIREMENTS="a? ( b )" |
74 |
if USE="-a b" is used, the package manager should enable a because it's |
75 |
needed for b and it should show this. We could say we also can disable b |
76 |
but we can't know if a USE flag is disabled or just not enabled (in |
77 |
other words, because every USE flags is disabled by default). In |
78 |
addition, we can consider if someone want to enable a feature it should |
79 |
be more important than disabling another. |
80 |
|
81 |
* if a then not b |
82 |
IUSE_REQUIREMENTS="a? ( -b )" |
83 |
if USE="a b", b should be disabled by the PM. It's up to the maintainer |
84 |
to choose a default behavior by setting the relation between USE flags |
85 |
(b? ( -a ) is equivalent but will disable a). |
86 |
|
87 |
* at least one of a b c, possibly only if d |
88 |
IUSE_REQUIREMENTS="d? ( || ( a b c ) )" |
89 |
if USE="d", the PM will enable a. |
90 |
|
91 |
* exactly one of a b c, possibly only if d |
92 |
IUSE_REQUIREMENTS="d? ( || ( a b c ) ) a? ( -b -c ) b? ( -a -c ) c? ( -a |
93 |
-b )" |
94 |
if USE="d", same as before. |
95 |
if USE="d a", nothing |
96 |
if USE="d a b", it's harder because a? ( -b -c ) and b? ( -a -c ). We |
97 |
can imagine to disable b because a is the first value in || ( a b c ) |
98 |
but it's not satisfying. We can imagine another operator like | to |
99 |
represent this dependency: "d? ( | ( a b c ) )" |
100 |
|
101 |
* at most one of a b c, possibly only if d |
102 |
IUSE_REQUIREMENTS="d? ( a? ( -b -c) b? ( -a -c ) c? ( -a -b) )" |
103 |
it's quite similar to the previous one but here it's harder to guess |
104 |
which one should be keep if USE="d a b". |
105 |
As previously, we can imagine another operator like "d? ( ||| ( a b c ) )" |
106 |
|
107 |
But if we want to move to a really generic specification, we can |
108 |
introduce something similar to Exherbos syntax: |
109 |
exactly-N, max-N, min-N with N as a positive integer. |
110 |
So, we could write: |
111 |
"d? ( exactly-1? ( a b c ) )" |
112 |
"d? ( max-1? ( a b c ) )" |
113 |
"d? ( min-1? ( a b c ) )" |
114 |
With this syntax, it's easy to consider first values as one to use by |
115 |
default for the PM (so, never failing). |
116 |
|
117 |
The only big issue I see with this syntax is it will make exactly-N, |
118 |
max-N and min-N no valid USE flags. But we can prevent that by prefixing |
119 |
the name by an illegal character like ||exactly-1. |
120 |
|
121 |
About the dying thing, I just want to precise I don't want to add a |
122 |
feature that will only die with a cool message. Maintainers can do that. |
123 |
The idea is to prevent maintainers to do that without silently enabling |
124 |
a feature or moving to an unstable state (because of EAPI-2 use |
125 |
dependencies). |
126 |
It will let maintainers to die if they want. They will not have to set |
127 |
"a? ( b )" if they really think a shouldn't be enabled (even with |
128 |
possible user knowledge) if b is enabled. In this case, the classic die |
129 |
statement will be ok. |
130 |
|
131 |
Thanks, |
132 |
Mounir |