From cc7666a3162001ca4fb692dedbfd2ae8ae0b79f5 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sun, 25 May 2008 01:44:03 +0000 Subject: [PATCH] Add support for conditionals inside USE dependencies. This is useful for cases in which the package satisfying a dependency should have identical or opposite flag state relative to the parent package. Conditionals are evaluated as follows: parent state conditional result x [x?] [x] -x [x?] [-x] x [-x?] [-x] -x [-x?] [x] svn path=/main/trunk/; revision=10396 --- pym/portage/__init__.py | 22 ++++++++++++++++---- pym/portage/dep.py | 46 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index dfe7ddeb0..80c24ff31 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -5403,6 +5403,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", if kwargs["use_binaries"]: portdb = trees[myroot]["bintree"].dbapi myvirtuals = mysettings.getvirtuals() + myuse = kwargs["myuse"] for x in mysplit: if x == "||": newsplit.append(x) @@ -5411,10 +5412,23 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", newsplit.append(_expand_new_virtuals(x, edebug, mydbapi, mysettings, myroot=myroot, trees=trees, **kwargs)) continue - if portage.dep._dep_check_strict and \ - not isvalidatom(x, allow_blockers=True): - raise portage.exception.ParseError( - "invalid atom: '%s'" % x) + + if not isinstance(x, portage.dep.Atom): + try: + x = portage.dep.Atom(x) + except portage.exception.InvalidAtom: + if portage.dep._dep_check_strict: + raise portage.exception.ParseError( + "invalid atom: '%s'" % x) + + if isinstance(x, portage.dep.Atom) and x.use: + if x.use.conditional: + evaluated_atom = portage.dep.remove_slot(x) + if x.slot: + evaluated_atom += ":%s" % x.slot + evaluated_atom += str(x.use.evaluate_conditionals(myuse)) + x = portage.dep.Atom(evaluated_atom) + mykey = dep_getkey(x) if not mykey.startswith("virtual/"): newsplit.append(x) diff --git a/pym/portage/dep.py b/pym/portage/dep.py index 3e642b517..6881b1734 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -19,6 +19,7 @@ # import re, sys, types +from itertools import chain import portage.exception from portage.exception import InvalidData, InvalidAtom from portage.versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify @@ -340,15 +341,52 @@ class _use_dep(object): def __init__(self, use): enabled_flags = [] disabled_flags = [] + conditional_enabled = [] + conditional_disabled = [] for x in use: if "-" == x[:1]: - disabled_flags.append(x[1:]) + if "?" == x[-1:]: + conditional_disabled.append(x[1:-1]) + else: + disabled_flags.append(x[1:]) else: - enabled_flags.append(x) + if "?" == x[-1:]: + conditional_enabled.append(x[:-1]) + else: + enabled_flags.append(x) self.tokens = use + if not isinstance(self.tokens, tuple): + self.tokens = tuple(self.tokens) self.enabled = frozenset(enabled_flags) self.disabled = frozenset(disabled_flags) - self.required = self.enabled.union(self.disabled) + self.conditional_enabled = frozenset(conditional_enabled) + self.conditional_disabled = frozenset(conditional_disabled) + self.conditional = self.conditional_enabled.union( + self.conditional_disabled) + self.required = frozenset(chain(self.enabled, self.disabled, + self.conditional_enabled, self.conditional_disabled)) + + def __str__(self): + return "".join("[%s]" % x for x in self.tokens) + + def evaluate_conditionals(self, use): + """ + Create a new instance with conditionals evaluated as follows: + + parent state conditional result + x x? x + -x x? -x + x -x? -x + -x -x? x + """ + tokens = [] + tokens.extend(self.enabled) + tokens.extend("-" + x for x in self.disabled) + tokens.extend(self.conditional_enabled.intersection(use)) + tokens.extend("-" + x for x in self.conditional_enabled.difference(use)) + tokens.extend("-" + x for x in self.conditional_disabled.intersection(use)) + tokens.extend(self.conditional_disabled.difference(use)) + return _use_dep(tokens) class Atom(str): @@ -519,7 +557,7 @@ def dep_getusedeps( depend ): open_bracket = depend.find( '[', open_bracket+1 ) return tuple(use_list) -_invalid_atom_chars_regexp = re.compile("[()|?@]") +_invalid_atom_chars_regexp = re.compile("[()|@]") def isvalidatom(atom, allow_blockers=False): """ -- 2.26.2