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