From 5e39119d80433d9333fac70d12cf7c6b6ca61afe Mon Sep 17 00:00:00 2001 From: Sebastian Luther Date: Wed, 24 Mar 2010 08:22:58 +0100 Subject: [PATCH] Implement use dependency defaults --- bin/repoman | 2 + pym/_emerge/Package.py | 2 +- pym/_emerge/depgraph.py | 32 ++- pym/_emerge/resolver/slot_collision.py | 10 +- pym/portage/dbapi/__init__.py | 8 +- pym/portage/dep/__init__.py | 248 ++++++++++++++---- pym/portage/dep/dep_check.py | 7 +- pym/portage/eapi.py | 3 + pym/portage/tests/dep/testAtom.py | 237 ++++++++++++----- pym/portage/tests/dep/test_match_from_list.py | 106 ++++++-- .../tests/resolver/test_use_dep_defaults.py | 40 +++ 11 files changed, 543 insertions(+), 152 deletions(-) create mode 100644 pym/portage/tests/resolver/test_use_dep_defaults.py diff --git a/bin/repoman b/bin/repoman index 71fb58ac3..97566d3f1 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1619,6 +1619,8 @@ for x in scanlist: myteststr = mydepstr[len(token):] else: myteststr = mydepstr + myteststr = myteststr.replace("(+)", "") + myteststr = myteststr.replace("(-)", "") if myteststr.endswith(" "+token): myteststr = myteststr[:-len(token)] while myteststr.find(" "+token+" ") != -1: diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index 90a5d03eb..0cc36e18f 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -48,7 +48,7 @@ class Package(Task): # Avoid an InvalidAtom exception when creating slot_atom. # This package instance will be masked due to empty SLOT. slot = '0' - if (self.iuse.enabled or self.iuse.enabled) and \ + if (self.iuse.enabled or self.iuse.disabled) and \ not eapi_has_iuse_defaults(self.metadata["EAPI"]): self._invalid_metadata('IUSE.invalid', "IUSE contains defaults, but EAPI doesn't allow them") diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 56ea1bd19..e3a47e8a7 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2078,7 +2078,7 @@ class depgraph(object): masked_pkg_instances.add(pkg) if atom.unevaluated_atom.use: if not pkg.iuse.is_valid_flag(atom.unevaluated_atom.use.required) \ - or atom.violated_conditionals(self._pkg_use_enabled(pkg)).use: + or atom.violated_conditionals(self._pkg_use_enabled(pkg), pkg.iuse.all).use: missing_use.append(pkg) if not mreasons: continue @@ -2097,14 +2097,22 @@ class depgraph(object): missing_iuse_reasons = [] for pkg in missing_use: use = self._pkg_use_enabled(pkg) - missing_iuse = pkg.iuse.get_missing_iuse(atom.use.required) + missing_iuse = [] + for x in pkg.iuse.get_missing_iuse(atom.use.required): + #FIXME: If a use flag occures more then it might be possible that + #one has a default one doesn't. + if x not in atom.use.missing_enabled and \ + x not in atom.use.missing_disabled: + missing_iuse.append(x) + mreasons = [] if missing_iuse: mreasons.append("Missing IUSE: %s" % " ".join(missing_iuse)) missing_iuse_reasons.append((pkg, mreasons)) else: - need_enable = sorted(atom.use.enabled.difference(use)) - need_disable = sorted(atom.use.disabled.intersection(use)) + need_enable = sorted(atom.use.enabled.difference(use).intersection(pkg.iuse.all)) + need_disable = sorted(atom.use.disabled.intersection(use).intersection(pkg.iuse.all)) + if need_enable or need_disable: changes = [] changes.extend(colorize("red", "+" + x) \ @@ -2118,7 +2126,7 @@ class depgraph(object): # Lets see if the violated use deps are conditional. # If so, suggest to change them on the parent. mreasons = [] - violated_atom = atom.unevaluated_atom.violated_conditionals(self._pkg_use_enabled(pkg), myparent.use.enabled) + violated_atom = atom.unevaluated_atom.violated_conditionals(self._pkg_use_enabled(pkg), pkg.iuse.all, myparent.use.enabled) if not (violated_atom.use.enabled or violated_atom.use.disabled): #all violated use deps are conditional changes = [] @@ -2625,7 +2633,13 @@ class depgraph(object): found_available_arg = True if atom.use: - missing_iuse = pkg.iuse.get_missing_iuse(atom.use.required) + missing_iuse = [] + for x in pkg.iuse.get_missing_iuse(atom.use.required): + #FIXME: If a use flag occures more then it might be possible that + #one has a default one doesn't. + if x not in atom.use.missing_enabled and \ + x not in atom.use.missing_disabled: + missing_iuse.append(x) if missing_iuse: # Don't add this to packages_with_invalid_use_config # since IUSE cannot be adjusted by the user. @@ -2641,11 +2655,13 @@ class depgraph(object): else: use = self._pkg_use_enabled(pkg) - if atom.use.enabled.difference(use): + if atom.use.enabled.difference(use) and \ + atom.use.enabled.difference(use).difference(atom.use.missing_enabled.difference(pkg.iuse.all)): if not pkg.built: packages_with_invalid_use_config.append(pkg) continue - if atom.use.disabled.intersection(use): + if atom.use.disabled.intersection(use) or \ + atom.use.disabled.difference(pkg.iuse.all).difference(atom.use.missing_disabled): if not pkg.built: packages_with_invalid_use_config.append(pkg) continue diff --git a/pym/_emerge/resolver/slot_collision.py b/pym/_emerge/resolver/slot_collision.py index 8b499ec00..b11fcb0c7 100644 --- a/pym/_emerge/resolver/slot_collision.py +++ b/pym/_emerge/resolver/slot_collision.py @@ -211,7 +211,8 @@ class slot_conflict_handler(object): collision_reasons[("version", sub_type)] = atoms elif not atom_set.findAtomForPackage(other_pkg): #Use conditionals not met. - violated_atom = atom.violated_conditionals(other_pkg.use.enabled, ppkg.use.enabled) + violated_atom = atom.violated_conditionals(other_pkg.use.enabled, \ + other_pkg.iuse.all, ppkg.use.enabled) for flag in violated_atom.use.enabled.union(violated_atom.use.disabled): atoms = collision_reasons.get(("use", flag), set()) atoms.add((ppkg, atom, other_pkg)) @@ -251,7 +252,7 @@ class slot_conflict_handler(object): conditional_matches = set() for ppkg, atom, other_pkg in parents: violated_atom = atom.unevaluated_atom.violated_conditionals( \ - other_pkg.use.enabled, ppkg.use.enabled) + other_pkg.use.enabled, other_pkg.iuse.all, ppkg.use.enabled) if use in violated_atom.use.enabled.union(violated_atom.use.disabled): hard_matches.add((ppkg, atom)) else: @@ -456,9 +457,10 @@ class slot_conflict_handler(object): if ppkg.installed: #We cannot assume that it's possible to reinstall the package. Do not #check if some of its atom has use.conditional - violated_atom = atom.violated_conditionals(pkg.use.enabled, ppkg.use.enabled) + violated_atom = atom.violated_conditionals(pkg.use.enabled, pkg.iuse.all, ppkg.use.enabled) else: - violated_atom = atom.unevaluated_atom.violated_conditionals(pkg.use.enabled, ppkg.use.enabled) + violated_atom = atom.unevaluated_atom.violated_conditionals(pkg.use.enabled, \ + pkg.iuse.all, ppkg.use.enabled) if pkg.installed and (violated_atom.use.enabled or violated_atom.use.disabled): #We can't change USE of an installed package (only of an ebuild, but that is already diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index 4799b2582..505a4b158 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -156,15 +156,17 @@ class dbapi(object): iuse = frozenset(x.lstrip('+-') for x in iuse.split()) missing_iuse = False for x in atom.use.required: - if x not in iuse and iuse_implicit_re.match(x) is None: + if x not in iuse and x not in atom.use.missing_enabled \ + and x not in atom.use.missing_disabled and iuse_implicit_re.match(x) is None: missing_iuse = True break if missing_iuse: continue if not self._use_mutable: - if atom.use.enabled.difference(use): + if atom.use.enabled.difference(use).difference(atom.use.missing_enabled): continue - if atom.use.disabled.intersection(use): + if atom.use.disabled.intersection(use) or \ + atom.use.disabled.difference(iuse).difference(atom.use.missing_disabled): continue else: # Check masked and forced flags for repoman. diff --git a/pym/portage/dep/__init__.py b/pym/portage/dep/__init__.py index 4c15b787c..6c12c96d2 100644 --- a/pym/portage/dep/__init__.py +++ b/pym/portage/dep/__init__.py @@ -332,8 +332,15 @@ def use_reduce(depstr, uselist=[], masklist=[], matchall=False, excludeall=[], i else: if need_bracket or "(" in token or ")" in token or "|" in token or \ (need_simple_token and "/" in token): - raise portage.exception.InvalidDependString( - _("malformed syntax: '%s'") % depstr) + if not (need_bracket or "|" in token or (need_simple_token and "/" in token)): + #We have '(' and/or ')' in token. Make sure it's not a use dep default + tmp = token.replace("(+)", "").replace("(-)", "") + if "(" in tmp or ")" in tmp: + raise portage.exception.InvalidDependString( + _("malformed syntax: '%s'") % depstr) + else: + raise portage.exception.InvalidDependString( + _("malformed syntax: '%s'") % depstr) if token[-1] == "?": need_bracket = True @@ -403,17 +410,21 @@ def flatten(mylist): class _use_dep(object): - __slots__ = ("__weakref__", "conditional", + __slots__ = ("__weakref__", "conditional", "missing_enabled", "missing_disabled", "disabled", "enabled", "tokens", "required") _conditionals_class = portage.cache.mappings.slot_dict_class( ("disabled", "enabled", "equal", "not_equal"), prefix="") - _valid_use_re = re.compile(r'^[^-?!=][^?!=]*$') + _valid_use_re = re.compile(r'^[A-Za-z0-9][A-Za-z0-9+_@-]*$') def __init__(self, use): enabled_flags = [] disabled_flags = [] + missing_enabled = [] + missing_disabled = [] + no_default = [] + conditional = self._conditionals_class() for k in conditional.allowed_keys: conditional[k] = [] @@ -421,37 +432,61 @@ class _use_dep(object): for x in use: last_char = x[-1:] first_char = x[:1] + flag = x + default = "" + if last_char in ("?", "="): + flag = flag[:-1] + if first_char in ("-", "!"): + flag = flag[1:] + + if flag[-3:] in ("(+)", "(-)"): + default = flag[-3:] + flag = flag[:-3] if "?" == last_char: if "!" == first_char: conditional.disabled.append( - self._validate_flag(x, x[1:-1])) + self._validate_flag(x, flag)) elif first_char in ("-", "=", "?"): raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) else: conditional.enabled.append( - self._validate_flag(x, x[:-1])) + self._validate_flag(x, flag)) elif "=" == last_char: if "!" == first_char: conditional.not_equal.append( - self._validate_flag(x, x[1:-1])) + self._validate_flag(x, flag)) elif first_char in ("-", "=", "?"): raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) else: conditional.equal.append( - self._validate_flag(x, x[:-1])) + self._validate_flag(x, flag)) elif last_char in ("!", "-"): raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) else: if "-" == first_char: - disabled_flags.append(self._validate_flag(x, x[1:])) + disabled_flags.append(self._validate_flag(x, flag)) elif first_char in ("!", "=", "?"): raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) else: - enabled_flags.append(self._validate_flag(x, x)) + enabled_flags.append(self._validate_flag(x, flag)) + + if default: + if default == "(+)": + if flag in missing_disabled or flag in no_default: + raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) + missing_enabled.append(flag) + else: + if flag in missing_enabled or flag in no_default: + raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) + missing_disabled.append(flag) + else: + if flag in missing_enabled or flag in missing_disabled: + raise InvalidAtom(_("Invalid use dep: '%s'") % (x,)) + no_default.append(flag) self.tokens = use if not isinstance(self.tokens, tuple): @@ -465,6 +500,8 @@ class _use_dep(object): self.enabled = frozenset(enabled_flags) self.disabled = frozenset(disabled_flags) + self.missing_enabled = frozenset(missing_enabled) + self.missing_disabled = frozenset(missing_disabled) self.conditional = None for v in conditional.values(): @@ -493,6 +530,22 @@ class _use_dep(object): def __repr__(self): return "portage.dep._use_dep(%s)" % repr(self.tokens) + + def _append_use_default(self, output, flag): + default = None + if flag in self.missing_enabled: + default = "(+)" + elif flag in self.missing_disabled: + default = "(-)" + + if not default: + return output + + if output[-1] in ("=", "?"): + return output[:-1] + default + output[-1] + else: + return output + default + def evaluate_conditionals(self, use): """ Create a new instance with conditionals evaluated. @@ -524,37 +577,114 @@ class _use_dep(object): tokens = [] conditional = self.conditional - tokens.extend(self.enabled) - tokens.extend("-" + x for x in self.disabled) - tokens.extend(x for x in conditional.enabled if x in use) - tokens.extend("-" + x for x in conditional.disabled if x not in use) + tokens.extend(self._append_use_default(x, x) for x in self.enabled) + tokens.extend(self._append_use_default("-" + x, x) for x in self.disabled) + tokens.extend(self._append_use_default(x, x) for x in conditional.enabled if x in use) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.disabled if x not in use) - tokens.extend(x for x in conditional.equal if x in use) - tokens.extend("-" + x for x in conditional.equal if x not in use) - tokens.extend("-" + x for x in conditional.not_equal if x in use) - tokens.extend(x for x in conditional.not_equal if x not in use) + tokens.extend(self._append_use_default(x, x) for x in conditional.equal if x in use) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.equal if x not in use) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.not_equal if x in use) + tokens.extend(self._append_use_default(x, x) for x in conditional.not_equal if x not in use) return _use_dep(tokens) - def violated_conditionals(self, other_use, parent_use=None): + def violated_conditionals(self, other_use, iuse, parent_use=None): """ Create a new instance with satisfied use deps removed. """ tokens = [] conditional = self.conditional - tokens.extend(x for x in self.enabled if x not in other_use) - tokens.extend("-" + x for x in self.disabled if x in other_use) - if conditional: - if parent_use is None: - raise InvalidAtom("violated_conditionals needs 'parent_use'" + \ - " parameter for conditional flags.") - tokens.extend(x + "?" for x in conditional.enabled if x in parent_use and not x in other_use) - tokens.extend("!" + x + "?" for x in conditional.disabled if x not in parent_use and x in other_use) - tokens.extend(x + "=" for x in conditional.equal if x in parent_use and x not in other_use) - tokens.extend(x + "=" for x in conditional.equal if x not in parent_use and x in other_use) - tokens.extend("!" + x + "=" for x in conditional.not_equal if x in parent_use and x in other_use) - tokens.extend("!" + x + "=" for x in conditional.not_equal if x not in parent_use and x not in other_use) + + for x in self.enabled: + if x not in other_use: + if x in iuse: + tokens.append(self._append_use_default(x, x)) + else: + if x in self.missing_disabled: + tokens.append(self._append_use_default(x, x)) + + for x in self.disabled: + if x not in other_use: + if x not in iuse: + if x in self.missing_enabled: + tokens.append(self._append_use_default("-" + x, x)) + else: + tokens.append(self._append_use_default("-" + x, x)) + + if not conditional: + return _use_dep(tokens) + + if parent_use is None: + raise InvalidAtom("violated_conditionals needs 'parent_use'" + \ + " parameter for conditional flags.") + + for x in conditional.enabled: + if x not in parent_use: + continue + + if x not in other_use: + if x in iuse: + tokens.append(self._append_use_default(x + "?", x)) + else: + if x in self.missing_disabled: + tokens.append(self._append_use_default(x + "?", x)) + + for x in conditional.disabled: + if x in parent_use: + continue + + if x not in other_use: + if x not in iuse: + if x in self.missing_enabled: + tokens.append(self._append_use_default("!" + x + "?", x)) + else: + tokens.append(self._append_use_default("!" + x + "?", x)) + + for x in conditional.equal: + if x not in parent_use: + continue + + if x not in other_use: + if x in iuse: + tokens.append(self._append_use_default(x + "=", x)) + else: + if x in self.missing_disabled: + tokens.append(self._append_use_default(x + "=", x)) + + for x in conditional.equal: + if x in parent_use: + continue + + if x not in other_use: + if x not in iuse: + if x in self.missing_enabled: + tokens.append(self._append_use_default(x + "=", x)) + else: + tokens.append(self._append_use_default(x + "=", x)) + + for x in conditional.not_equal: + if x in parent_use: + continue + + if x not in other_use: + if x in iuse: + tokens.append(self._append_use_default("!" + x + "=", x)) + else: + if x in self.missing_disabled: + tokens.append(self._append_use_default("!" + x + "=", x)) + + for x in conditional.not_equal: + if x not in parent_use: + continue + + if x not in other_use: + if x not in iuse: + if x in self.missing_enabled: + tokens.append(self._append_use_default("!" + x + "=", x)) + else: + tokens.append(self._append_use_default("!" + x + "=", x)) return _use_dep(tokens) @@ -571,15 +701,15 @@ class _use_dep(object): tokens = [] conditional = self.conditional - tokens.extend(self.enabled) - tokens.extend("-" + x for x in self.disabled) - tokens.extend(x for x in conditional.enabled if x not in use_mask) - tokens.extend("-" + x for x in conditional.disabled if x not in use_force) + tokens.extend(self._append_use_default(x, x) for x in self.enabled) + tokens.extend(self._append_use_default("-" + x, x) for x in self.disabled) + tokens.extend(self._append_use_default(x, x) for x in conditional.enabled if x not in use_mask) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.disabled if x not in use_force) - tokens.extend(x for x in conditional.equal if x not in use_mask) - tokens.extend("-" + x for x in conditional.equal if x not in use_force) - tokens.extend("-" + x for x in conditional.not_equal if x not in use_mask) - tokens.extend(x for x in conditional.not_equal if x not in use_force) + tokens.extend(self._append_use_default(x, x) for x in conditional.equal if x not in use_mask) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.equal if x not in use_force) + tokens.extend(self._append_use_default("-" + x, x) for x in conditional.not_equal if x not in use_mask) + tokens.extend(self._append_use_default(x, x) for x in conditional.not_equal if x not in use_force) return _use_dep(tokens) @@ -744,7 +874,7 @@ class Atom(_atom_base): atom += str(self.use.evaluate_conditionals(use)) return Atom(atom, unevaluated_atom=self) - def violated_conditionals(self, other_use, parent_use=None): + def violated_conditionals(self, other_use, iuse, parent_use=None): """ Create an atom instance with any USE conditional removed, that is satisfied by other_use. @@ -760,7 +890,7 @@ class Atom(_atom_base): atom = remove_slot(self) if self.slot: atom += ":%s" % self.slot - atom += str(self.use.violated_conditionals(other_use, parent_use)) + atom += str(self.use.violated_conditionals(other_use, iuse, parent_use)) return Atom(atom, unevaluated_atom=self) def _eval_qa_conditionals(self, use_mask, use_force): @@ -1341,19 +1471,35 @@ def match_from_list(mydep, candidate_list): use = getattr(x, "use", None) if use is not None: is_valid_flag = x.iuse.is_valid_flag - missing_iuse = False - for y in mydep.use.required: - if not is_valid_flag(y): - missing_iuse = True - break - if missing_iuse: - continue - if mydep.use.enabled.difference(use.enabled): + use_config_mismatch = False + + for y in mydep.use.enabled: + if is_valid_flag(y): + if y not in use.enabled: + use_config_mismatch = True + break + else: + if y not in mydep.use.missing_enabled: + use_config_mismatch = True + break + + if use_config_mismatch: continue - if mydep.use.disabled.intersection(use.enabled): + + for y in mydep.use.disabled: + if is_valid_flag(y): + if y in use.enabled: + use_config_mismatch = True + break + else: + if y not in mydep.use.missing_disabled: + use_config_mismatch = True + break + + if use_config_mismatch: continue - mylist.append(x) + mylist.append(x) return mylist def check_required_use(required_use, use, iuse): diff --git a/pym/portage/dep/dep_check.py b/pym/portage/dep/dep_check.py index be24ad81a..28d5771a7 100644 --- a/pym/portage/dep/dep_check.py +++ b/pym/portage/dep/dep_check.py @@ -8,7 +8,8 @@ import logging import portage from portage.dep import Atom, dep_opconvert, match_from_list, \ remove_slot, use_reduce -from portage.eapi import eapi_has_strong_blocks, eapi_has_use_deps, eapi_has_slot_deps +from portage.eapi import eapi_has_strong_blocks, eapi_has_use_deps, eapi_has_slot_deps, \ + eapi_has_use_dep_defaults from portage.exception import InvalidAtom, InvalidDependString, ParseError from portage.localization import _ from portage.util import writemsg, writemsg_level @@ -75,6 +76,10 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", if x.slot and not eapi_has_slot_deps(eapi): raise ParseError( _("invalid atom: '%s'") % (x,)) + if x.use and (x.use.missing_enabled or x.use.missing_disabled) \ + and not eapi_has_use_dep_defaults(eapi): + raise ParseError( + _("invalid atom: '%s'") % (x,)) if repoman: x = x._eval_qa_conditionals(use_mask, use_force) diff --git a/pym/portage/eapi.py b/pym/portage/eapi.py index a288b1964..eb2809ee8 100644 --- a/pym/portage/eapi.py +++ b/pym/portage/eapi.py @@ -42,3 +42,6 @@ def eapi_has_dosed_dohard(eapi): def eapi_has_required_use(eapi): return eapi not in ("0", "1", "2", "3") + +def eapi_has_use_dep_defaults(eapi): + return eapi not in ("0", "1", "2", "3") diff --git a/pym/portage/tests/dep/testAtom.py b/pym/portage/tests/dep/testAtom.py index 7d5ae3e79..fecf2bfa0 100644 --- a/pym/portage/tests/dep/testAtom.py +++ b/pym/portage/tests/dep/testAtom.py @@ -1,5 +1,4 @@ -# test_isvalidatom.py -- Portage Unit Testing Functionality -# Copyright 2006 Gentoo Foundation +# Copyright 2006, 2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from portage.tests import TestCase @@ -7,37 +6,43 @@ from portage.dep import Atom from portage.exception import InvalidAtom class TestAtom(TestCase): - """ A simple testcase for isvalidatom - """ def testAtom(self): - tests = [ - ( "=sys-apps/portage-2.1-r1:0[doc,a=,!b=,c?,!d?,-e]", + tests = ( + ( "=sys-apps/portage-2.1-r1:0[doc,a=,!b=,c?,!d?,-e]", ('=', 'sys-apps/portage', '2.1-r1', '0', '[doc,a=,!b=,c?,!d?,-e]'), False ), - ( "=sys-apps/portage-2.1-r1*:0[doc]", + ( "=sys-apps/portage-2.1-r1*:0[doc]", ('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]'), False ), - ( "sys-apps/portage:0[doc]", + ( "sys-apps/portage:0[doc]", (None, 'sys-apps/portage', None, '0', '[doc]'), False ), - ( "sys-apps/portage:0[doc]", + ( "sys-apps/portage:0[doc]", (None, 'sys-apps/portage', None, '0', '[doc]'), False ), - ( "*/*", + ( "*/*", (None, '*/*', None, None, None), True ), - ( "sys-apps/*", + ( "sys-apps/*", (None, 'sys-apps/*', None, None, None), True ), - ( "*/portage", + ( "*/portage", (None, '*/portage', None, None, None), True ), - ( "s*s-*/portage:1", + ( "s*s-*/portage:1", (None, 's*s-*/portage', None, '1', None), True ), - ( "*/po*ge:2", + ( "*/po*ge:2", (None, '*/po*ge', None, '2', None), True ), - ( "!dev-libs/A", + ( "!dev-libs/A", (None, 'dev-libs/A', None, None, None), True ), - ( "!!dev-libs/A", + ( "!!dev-libs/A", (None, 'dev-libs/A', None, None, None), True ), - ] + ( "!!dev-libs/A", + (None, 'dev-libs/A', None, None, None), True ), + ( "dev-libs/A[foo(+)]", + (None, 'dev-libs/A', None, None, "[foo(+)]"), True ), + ( "dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", + (None, 'dev-libs/A', None, None, "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ), + ( "dev-libs/A:2[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", + (None, 'dev-libs/A', None, "2", "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ), + ) - tests_xfail = [ + tests_xfail = ( ( Atom("sys-apps/portage"), False ), ( "cat/pkg[a!]", False ), ( "cat/pkg[a-]", False ), @@ -64,90 +69,157 @@ class TestAtom(TestCase): ( "*/portage", False ), ( "*/**", True ), ( "*/portage[use]", True ), - ( "*/portage:slot", True ) - ] + ( "cat/pkg[a()]", False ), + ( "cat/pkg[a(]", False ), + ( "cat/pkg[a)]", False ), + ( "cat/pkg[a(,b]", False ), + ( "cat/pkg[a),b]", False ), + ( "cat/pkg[a(*)]", False ), + ( "cat/pkg[a(*)]", True ), + ( "cat/pkg[a(+-)]", False ), + ( "cat/pkg[a()]", False ), + ( "cat/pkg[(+)a]", False ), + ( "cat/pkg[a=(+)]", False ), + ( "cat/pkg[!(+)a=]", False ), + ( "cat/pkg[!a=(+)]", False ), + ( "cat/pkg[a?(+)]", False ), + ( "cat/pkg[!a?(+)]", False ), + ( "cat/pkg[!(+)a?]", False ), + ( "cat/pkg[-(+)a]", False ), + ( "cat/pkg[a(+),-a]", False ), + ( "cat/pkg[a(-),-a]", False ), + ( "cat/pkg[-a,a(+)]", False ), + ( "cat/pkg[-a,a(-)]", False ), + ( "cat/pkg[-a(+),a(-)]", False ), + ( "cat/pkg[-a(-),a(+)]", False ), + ) for atom, parts, allow_wildcard in tests: a = Atom(atom, allow_wildcard=allow_wildcard) op, cp, ver, slot, use = parts self.assertEqual( op, a.operator, - msg="Atom('%s').operator == '%s'" % ( atom, a.operator ) ) + msg="Atom('%s').operator = %s == '%s'" % ( atom, a.operator, op ) ) self.assertEqual( cp, a.cp, - msg="Atom('%s').cp == '%s'" % ( atom, a.cp ) ) + msg="Atom('%s').cp = %s == '%s'" % ( atom, a.cp, cp ) ) if ver is not None: cpv = "%s-%s" % (cp, ver) else: cpv = cp self.assertEqual( cpv, a.cpv, - msg="Atom('%s').cpv == '%s'" % ( atom, a.cpv ) ) + msg="Atom('%s').cpv = %s == '%s'" % ( atom, a.cpv, cpv ) ) self.assertEqual( slot, a.slot, - msg="Atom('%s').slot == '%s'" % ( atom, a.slot ) ) + msg="Atom('%s').slot = %s == '%s'" % ( atom, a.slot, slot ) ) if a.use: - expected_use = str(a.use) + returned_use = str(a.use) else: - expected_use = None - self.assertEqual( use, expected_use, - msg="Atom('%s').use == '%s'" % ( atom, a.use ) ) + returned_use = None + self.assertEqual( use, returned_use, + msg="Atom('%s').use = %s == '%s'" % ( atom, returned_use, use ) ) for atom, allow_wildcard in tests_xfail: - self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom) + self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom, allow_wildcard=allow_wildcard) + + def test_intersects(self): + test_cases = ( + ("dev-libs/A", "dev-libs/A", True), + ("dev-libs/A", "dev-libs/B", False), + ("dev-libs/A", "sci-libs/A", False), + ("dev-libs/A[foo]", "sci-libs/A[bar]", False), + ("dev-libs/A[foo(+)]", "sci-libs/A[foo(-)]", False), + ("=dev-libs/A-1", "=dev-libs/A-1-r1", False), + ("~dev-libs/A-1", "=dev-libs/A-1", False), + ("=dev-libs/A-1:1", "=dev-libs/A-1", True), + ("=dev-libs/A-1:1", "=dev-libs/A-1:1", True), + ("=dev-libs/A-1:1", "=dev-libs/A-1:2", False), + ) + + for atom, other, expected_result in test_cases: + self.assertEqual(Atom(atom).intersects(Atom(other)), expected_result, \ + "%s and %s should intersect: %s" % (atom, other, expected_result)) def test_violated_conditionals(self): test_cases = ( - ("dev-libs/A", ["foo"], None, "dev-libs/A"), - ("dev-libs/A[foo]", [], None, "dev-libs/A[foo]"), - ("dev-libs/A[foo]", ["foo"], None, "dev-libs/A"), - ("dev-libs/A[foo]", [], [], "dev-libs/A[foo]"), - ("dev-libs/A[foo]", ["foo"], [], "dev-libs/A"), + ("dev-libs/A", ["foo"], ["foo"], None, "dev-libs/A"), + ("dev-libs/A[foo]", [], ["foo"], None, "dev-libs/A[foo]"), + ("dev-libs/A[foo]", ["foo"], ["foo"], None, "dev-libs/A"), + ("dev-libs/A[foo]", [], ["foo"], [], "dev-libs/A[foo]"), + ("dev-libs/A[foo]", ["foo"], ["foo"], [], "dev-libs/A"), - ("dev-libs/A:0[foo]", ["foo"], [], "dev-libs/A:0"), + ("dev-libs/A:0[foo]", ["foo"], ["foo"], [], "dev-libs/A:0"), - ("dev-libs/A[foo,-bar]", [], None, "dev-libs/A[foo]"), - ("dev-libs/A[-foo,bar]", [], None, "dev-libs/A[bar]"), + ("dev-libs/A[foo,-bar]", [], ["foo", "bar"], None, "dev-libs/A[foo]"), + ("dev-libs/A[-foo,bar]", [], ["foo", "bar"], None, "dev-libs/A[bar]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], [], "dev-libs/A[a,!c=]"), - - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], [], "dev-libs/A[!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], [], "dev-libs/A[a,b=,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], [], "dev-libs/A[a]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], [], "dev-libs/A[a,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], [], "dev-libs/A[a,!e?,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], [], "dev-libs/A[a,-f,!c=]"), - - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a"], "dev-libs/A[!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["b"], "dev-libs/A[a,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["c"], "dev-libs/A[a,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["d"], "dev-libs/A[a,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["e"], "dev-libs/A[a,!c=]"), - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["f"], "dev-libs/A[a,-f,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!c=]"), + + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,b=,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,!e?,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a,-f,!c=]"), + + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a"], ["a", "b", "c", "d", "e", "f"], ["a"], "dev-libs/A[!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["b"], ["a", "b", "c", "d", "e", "f"], ["b"], "dev-libs/A[a,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["c"], ["a", "b", "c", "d", "e", "f"], ["c"], "dev-libs/A[a,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], ["a", "b", "c", "d", "e", "f"], ["d"], "dev-libs/A[a,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], ["a", "b", "c", "d", "e", "f"], ["e"], "dev-libs/A[a,!c=]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], ["a", "b", "c", "d", "e", "f"], ["f"], "dev-libs/A[a,-f,!c=]"), + + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["a"], ["a", "b", "c", "d", "e", "f"], ["a"], "dev-libs/A[!c(+)=]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["b"], ["a", "b", "c", "d", "e", "f"], ["b"], "dev-libs/A[a(-),!c(-)=]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["c"], ["a", "b", "c", "d", "e", "f"], ["c"], "dev-libs/A[a(+),!c(+)=]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], ["a", "b", "c", "d", "e", "f"], ["d"], "dev-libs/A[a(-),!c(-)=]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["e"], ["a", "b", "c", "d", "e", "f"], ["e"], "dev-libs/A[a(+),!c(+)=]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["f"], ["a", "b", "c", "d", "e", "f"], ["f"], "dev-libs/A[a(-),-f(+),!c(-)=]"), + + ("dev-libs/A[a(+),b(+)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["a"], ["a"], ["a"], "dev-libs/A[!e(+)?,b(+)=]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["b"], ["b"], ["b"], "dev-libs/A[a(-),-f(+),!c(-)=]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["c"], ["c"], ["c"], "dev-libs/A[!e(+)?,!c(+)=]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], ["d"], ["d"], "dev-libs/A[a(-),-f(+),b(+)=,!c(-)=]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["e"], ["e"], ["e"], "dev-libs/A"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["f"], ["f"], ["f"], "dev-libs/A[a(-),-f(+),b(+)=,!c(-)=]"), + + #Some more test cases to trigger all remaining code paths + ("dev-libs/B[x?]", [], ["x"], ["x"], "dev-libs/B[x?]"), + ("dev-libs/B[x(+)?]", [], [], ["x"], "dev-libs/B"), + ("dev-libs/B[x(-)?]", [], [], ["x"], "dev-libs/B[x(-)?]"), + + ("dev-libs/C[x=]", [], ["x"], ["x"], "dev-libs/C[x=]"), + ("dev-libs/C[x(+)=]", [], [], ["x"], "dev-libs/C"), + ("dev-libs/C[x(-)=]", [], [], ["x"], "dev-libs/C[x(-)=]"), + + ("dev-libs/D[!x=]", [], ["x"], ["x"], "dev-libs/D"), + ("dev-libs/D[!x(+)=]", [], [], ["x"], "dev-libs/D[!x(+)=]"), + ("dev-libs/D[!x(-)=]", [], [], ["x"], "dev-libs/D"), ) test_cases_xfail = ( - ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], None), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c", "d", "e", "f"], None), ) - for atom, other_use, parent_use, expected_violated_atom in test_cases: + for atom, other_use, iuse, parent_use, expected_violated_atom in test_cases: a = Atom(atom) - violated_atom = a.violated_conditionals(other_use, parent_use) + violated_atom = a.violated_conditionals(other_use, iuse, parent_use) if parent_use is None: - fail_msg = "Atom: %s, other_use: %s, parent_use: %s, got: %s, expected: %s" % \ - (atom, " ".join(other_use), "None", str(violated_atom), expected_violated_atom) + fail_msg = "Atom: %s, other_use: %s, iuse: %s, parent_use: %s, got: %s, expected: %s" % \ + (atom, " ".join(other_use), " ".join(iuse), "None", str(violated_atom), expected_violated_atom) else: - fail_msg = "Atom: %s, other_use: %s, parent_use: %s, got: %s, expected: %s" % \ - (atom, " ".join(other_use), " ".join(parent_use), str(violated_atom), expected_violated_atom) + fail_msg = "Atom: %s, other_use: %s, iuse: %s, parent_use: %s, got: %s, expected: %s" % \ + (atom, " ".join(other_use), " ".join(iuse), " ".join(parent_use), str(violated_atom), expected_violated_atom) self.assertEqual(str(violated_atom), expected_violated_atom, fail_msg) - for atom, other_use, parent_use in test_cases_xfail: + for atom, other_use, iuse, parent_use in test_cases_xfail: a = Atom(atom) self.assertRaisesMsg(atom, InvalidAtom, \ - a.violated_conditionals, other_use, parent_use) + a.violated_conditionals, other_use, iuse, parent_use) def test_evaluate_conditionals(self): test_cases = ( ("dev-libs/A[foo]", [], "dev-libs/A[foo]"), ("dev-libs/A[foo]", ["foo"], "dev-libs/A[foo]"), - ("dev-libs/A:0[foo]", ["foo"], "dev-libs/A:0[foo]"), + ("dev-libs/A:0[foo=]", ["foo"], "dev-libs/A:0[foo]"), ("dev-libs/A[foo,-bar]", [], "dev-libs/A[foo,-bar]"), ("dev-libs/A[-foo,bar]", [], "dev-libs/A[-foo,bar]"), @@ -159,8 +231,43 @@ class TestAtom(TestCase): ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d"], "dev-libs/A[a,-f,d,-e,-b,c]"), ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["e"], "dev-libs/A[a,-f,-b,c]"), ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["f"], "dev-libs/A[a,-f,-e,-b,c]"), + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", ["d"], "dev-libs/A[a(-),-f(+),d(+),-e(-),-b(+),c(-)]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", ["f"], "dev-libs/A[a(+),-f(-),-e(+),-b(-),c(+)]"), ) - - + for atom, use, expected_atom in test_cases: - self.assertEqual(str(Atom(atom).evaluate_conditionals(use)), expected_atom) + a = Atom(atom) + b = a.evaluate_conditionals(use) + self.assertEqual(str(b), expected_atom) + self.assertEqual(str(b.unevaluated_atom), atom) + + def test__eval_qa_conditionals(self): + test_cases = ( + ("dev-libs/A[foo]", [], [], "dev-libs/A[foo]"), + ("dev-libs/A[foo]", ["foo"], [], "dev-libs/A[foo]"), + ("dev-libs/A[foo]", [], ["foo"], "dev-libs/A[foo]"), + + ("dev-libs/A:0[foo]", [], [], "dev-libs/A:0[foo]"), + ("dev-libs/A:0[foo]", ["foo"], [], "dev-libs/A:0[foo]"), + ("dev-libs/A:0[foo]", [], ["foo"], "dev-libs/A:0[foo]"), + ("dev-libs/A:0[foo=]", [], ["foo"], "dev-libs/A:0[foo]"), + + ("dev-libs/A[foo,-bar]", ["foo"], ["bar"], "dev-libs/A[foo,-bar]"), + ("dev-libs/A[-foo,bar]", ["foo", "bar"], [], "dev-libs/A[-foo,bar]"), + + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["a", "b", "c"], [], "dev-libs/A[a,-f,d,-e,-b,c]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c"], "dev-libs/A[a,-f,d,-e,b,-c]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", ["d", "e", "f"], [], "dev-libs/A[a,-f,-e,b,-b,-c,c]"), + ("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["d", "e", "f"], "dev-libs/A[a,-f,d,b,-b,-c,c]"), + + ("dev-libs/A[a(-),b(+)=,!c(-)=,d(+)?,!e(-)?,-f(+)]", \ + ["a", "b", "c", "d", "e", "f"], [], "dev-libs/A[a(-),-f(+),-e(-),-b(+),c(-)]"), + ("dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", \ + [], ["a", "b", "c", "d", "e", "f"], "dev-libs/A[a(+),-f(-),d(-),b(-),-c(+)]"), + ) + + for atom, use_mask, use_force, expected_atom in test_cases: + a = Atom(atom) + b = a._eval_qa_conditionals(use_mask, use_force) + self.assertEqual(str(b), expected_atom) + self.assertEqual(str(b.unevaluated_atom), atom) diff --git a/pym/portage/tests/dep/test_match_from_list.py b/pym/portage/tests/dep/test_match_from_list.py index e5a418cd8..dac05567c 100644 --- a/pym/portage/tests/dep/test_match_from_list.py +++ b/pym/portage/tests/dep/test_match_from_list.py @@ -1,26 +1,94 @@ -# test_match_from_list.py -- Portage Unit Testing Functionality -# Copyright 2006 Gentoo Foundation +# Copyright 2006, 2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from portage.tests import TestCase -from portage.dep import match_from_list +from portage.dep import Atom, match_from_list +from portage.versions import catpkgsplit + +class Package(object): + """ + Provides a minimal subset of attributes of _emerge.Package.Package + """ + def __init__(self, atom): + atom = Atom(atom) + self.cp = atom.cp + self.cpv = atom.cpv + self.cpv_split = catpkgsplit(self.cpv) + self.slot = atom.slot + if atom.use: + self.use = self._use_class(atom.use.enabled) + self.iuse = self._iuse_class(atom.use.required) + else: + self.use = self._use_class([]) + self.iuse = self._iuse_class([]) + + class _use_class(object): + def __init__(self, use): + self.enabled = frozenset(use) + + class _iuse_class(object): + def __init__(self, iuse): + self.all = frozenset(iuse) + + def is_valid_flag(self, flags): + if isinstance(flags, basestring): + flags = [flags] + missing_iuse = [] + for flag in flags: + if not flag in self.all: + return False + return True class Test_match_from_list(TestCase): def testMatch_from_list(self): - tests = [ ("=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), - ("=sys-fs/udev-1*", ["sys-fs/udev-123"], ["sys-fs/udev-123"]), - ("=sys-fs/udev-4*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), - ("*/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), - ("sys-fs/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), - ("*/udev", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), - ("=sys-apps/portage-2*", ["sys-apps/portage-2.1"], ["sys-apps/portage-2.1"] ), - ("=sys-apps/portage-2.1*", ["sys-apps/portage-2.1.2"], ["sys-apps/portage-2.1.2"] ), - ("dev-libs/*", ["sys-apps/portage-2.1.2"], [] ), - ("*/tar", ["sys-apps/portage-2.1.2"], [] ), - ("*/*", ["dev-libs/A-1", "dev-libs/B-1"], ["dev-libs/A-1", "dev-libs/B-1"] ), - ("dev-libs/*", ["dev-libs/A-1", "sci-libs/B-1"], ["dev-libs/A-1"] ) - ] - - for atom, cpv_list, result in tests: - self.assertEqual( match_from_list( atom, cpv_list ), result ) + tests = ( + ("=sys-apps/portage-45*", [], [] ), + ("=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + ("!=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + ("!!=sys-apps/portage-45*", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + ("=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + ("=sys-apps/portage-045", ["sys-apps/portage-046"], [] ), + ("~sys-apps/portage-045", ["sys-apps/portage-045-r1"], ["sys-apps/portage-045-r1"] ), + ("~sys-apps/portage-045", ["sys-apps/portage-046-r1"], [] ), + ("<=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + ("<=sys-apps/portage-045", ["sys-apps/portage-046"], [] ), + ("=sys-apps/portage-045", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + (">=sys-apps/portage-047", ["sys-apps/portage-046-r1"], [] ), + (">sys-apps/portage-044", ["sys-apps/portage-045"], ["sys-apps/portage-045"] ), + (">sys-apps/portage-047", ["sys-apps/portage-046-r1"], [] ), + ("sys-apps/portage:0", [Package("=sys-apps/portage-045:0")], ["sys-apps/portage-045"] ), + ("sys-apps/portage:0", [Package("=sys-apps/portage-045:1")], [] ), + ("=sys-fs/udev-1*", ["sys-fs/udev-123"], ["sys-fs/udev-123"]), + ("=sys-fs/udev-4*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), + ("*/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), + ("sys-fs/*", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), + ("*/udev", ["sys-fs/udev-456"], ["sys-fs/udev-456"] ), + ("=sys-apps/portage-2*", ["sys-apps/portage-2.1"], ["sys-apps/portage-2.1"] ), + ("=sys-apps/portage-2.1*", ["sys-apps/portage-2.1.2"], ["sys-apps/portage-2.1.2"] ), + ("dev-libs/*", ["sys-apps/portage-2.1.2"], [] ), + ("*/tar", ["sys-apps/portage-2.1.2"], [] ), + ("*/*", ["dev-libs/A-1", "dev-libs/B-1"], ["dev-libs/A-1", "dev-libs/B-1"] ), + ("dev-libs/*", ["dev-libs/A-1", "sci-libs/B-1"], ["dev-libs/A-1"] ), + + ("dev-libs/A[foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], ["dev-libs/A-1"] ), + ("dev-libs/A[-foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], ["dev-libs/A-2"] ), + ("dev-libs/A[-foo]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2")], [] ), + ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo]")], [] ), + ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[-foo,bar]")], [] ), + ("dev-libs/A[foo,bar]", [Package("=dev-libs/A-1[foo]"), Package("=dev-libs/A-2[foo,bar]")], ["dev-libs/A-2"] ), + ("dev-libs/A[foo,bar(+)]", [Package("=dev-libs/A-1[-foo]"), Package("=dev-libs/A-2[foo]")], ["dev-libs/A-2"] ), + ("dev-libs/A[foo,bar(-)]", [Package("=dev-libs/A-1[-foo]"), Package("=dev-libs/A-2[foo]")], [] ), + ("dev-libs/A[foo,-bar(-)]", [Package("=dev-libs/A-1[-foo,bar]"), Package("=dev-libs/A-2[foo]")], ["dev-libs/A-2"] ), + ) + + for atom, cpv_list, expected_result in tests: + result = [] + for pkg in match_from_list( atom, cpv_list ): + if isinstance(pkg, Package): + result.append(pkg.cpv) + else: + result.append(pkg) + self.assertEqual( result, expected_result ) diff --git a/pym/portage/tests/resolver/test_use_dep_defaults.py b/pym/portage/tests/resolver/test_use_dep_defaults.py new file mode 100644 index 000000000..8f41e40c8 --- /dev/null +++ b/pym/portage/tests/resolver/test_use_dep_defaults.py @@ -0,0 +1,40 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import ResolverPlayground, ResolverPlaygroundTestCase + +class UseDepDefaultsTestCase(TestCase): + + def testUseDepDefaultse(self): + pass + #~ ebuilds = { + #~ "dev-libs/A-1": { "DEPEND": "dev-libs/B[foo]", "RDEPEND": "dev-libs/B[foo]", "EAPI": 2 }, + #~ "dev-libs/A-2": { "DEPEND": "dev-libs/B[foo(+)]", "RDEPEND": "dev-libs/B[foo(+)]", "EAPI": 4 }, + #~ "dev-libs/A-3": { "DEPEND": "dev-libs/B[foo(-)]", "RDEPEND": "dev-libs/B[foo(-)]", "EAPI": 4 }, + #~ "dev-libs/B-1": { "IUSE": "+foo", "EAPI": 1 }, + #~ "dev-libs/B-2": {}, + #~ } +#~ + #~ test_cases = ( + #~ ResolverPlaygroundTestCase( + #~ ["=dev-libs/A-1"], + #~ success = True, + #~ mergelist = ["dev-libs/B-1", "dev-libs/A-1"]), + #~ ResolverPlaygroundTestCase( + #~ ["=dev-libs/A-2"], + #~ success = True, + #~ mergelist = ["dev-libs/B-2", "dev-libs/A-2"]), + #~ ResolverPlaygroundTestCase( + #~ ["=dev-libs/A-3"], + #~ success = True, + #~ mergelist = ["dev-libs/B-1", "dev-libs/A-3"]), + #~ ) +#~ + #~ playground = ResolverPlayground(ebuilds=ebuilds) + #~ try: + #~ for test_case in test_cases: + #~ playground.run_TestCase(test_case) + #~ self.assertEqual(test_case.test_success, True, test_case.fail_msg) + #~ finally: + #~ playground.cleanup() -- 2.26.2