Support =*/*-*9999* wildcard atom, bug #402197.
authorZac Medico <zmedico@gentoo.org>
Wed, 18 Jul 2012 19:55:16 +0000 (12:55 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 18 Jul 2012 19:55:16 +0000 (12:55 -0700)
man/portage.5
pym/portage/dep/__init__.py
pym/portage/tests/dep/testAtom.py
pym/portage/tests/dep/test_best_match_to_list.py

index 9823eb1d5286865d20fc7d4fc3a63ad70abbc5f6..ad84ff1a758486ede8af414157a4a3cda814536b 100644 (file)
@@ -162,6 +162,9 @@ next to each other.
 
 .I Examples:
 .nf
+# match anything with a version containing 9999, which can be used in
+# package.mask to prevent emerge --autounmask from selecting live ebuilds
+=*/*-*9999*
 # match anything from the 'sys\-apps' category
 sys\-apps/*
 # match packages named 'zlib' from any category
index f0d07a52a090d91db779c0df95653f59c01c0146..8286e8dabb50603cdc6beb70a9560a69b6b089ae 100644 (file)
@@ -141,9 +141,10 @@ def _get_atom_wildcard_re(eapi_attrs):
        else:
                pkg_re = r'[\w+*][\w+*-]*?'
 
-       atom_re = re.compile(r'(?P<simple>(' +
-               _extended_cat + r')/(' + pkg_re +
-               r'))(:(?P<slot>' + _slot_loose + r'))?(' +
+       atom_re = re.compile(r'((?P<simple>(' +
+               _extended_cat + r')/(' + pkg_re + r'))' + \
+               '|(?P<star>=((' + _extended_cat + r')/(' + pkg_re + r'))-(?P<version>\*\d+\*)))' + \
+               '(:(?P<slot>' + _slot_loose + r'))?(' +
                _repo_separator + r'(?P<repo>' + _repo_name + r'))?$')
 
        _atom_wildcard_re_cache[cache_key] = atom_re
@@ -1243,18 +1244,27 @@ class Atom(_unicode):
                self.__dict__['blocker'] = blocker
                m = atom_re.match(s)
                extended_syntax = False
+               extended_version = None
                if m is None:
                        if allow_wildcard:
-                               m = _get_atom_wildcard_re(eapi_attrs).match(s)
+                               atom_re = _get_atom_wildcard_re(eapi_attrs)
+                               m = atom_re.match(s)
                                if m is None:
                                        raise InvalidAtom(self)
-                               op = None
                                gdict = m.groupdict()
-                               cpv = cp = gdict['simple']
+                               if m.group('star') is not None:
+                                       op = '=*'
+                                       base = atom_re.groupindex['star']
+                                       cp = m.group(base + 1)
+                                       cpv = m.group('star')[1:]
+                                       extended_version = m.group(base + 4)
+                               else:
+                                       op = None
+                                       cpv = cp = m.group('simple')
                                if cpv.find("**") != -1:
                                        raise InvalidAtom(self)
-                               slot = gdict['slot']
-                               repo = gdict['repo']
+                               slot = m.group('slot')
+                               repo = m.group('repo')
                                use_str = None
                                extended_syntax = True
                        else:
@@ -1297,7 +1307,7 @@ class Atom(_unicode):
                except InvalidData:
                        # plain cp, wildcard, or something
                        self.__dict__['cpv'] = cpv
-                       self.__dict__['version'] = None
+                       self.__dict__['version'] = extended_version
                self.__dict__['repo'] = repo
                if slot is None:
                        self.__dict__['slot'] = None
@@ -2003,19 +2013,23 @@ def best_match_to_list(mypkg, mylist):
        """
        operator_values = {'=':6, '~':5, '=*':4,
                '>':2, '<':2, '>=':2, '<=':2, None:1}
-       maxvalue = -2
+       maxvalue = -99
        bestm  = None
        mypkg_cpv = None
        for x in match_to_list(mypkg, mylist):
                if x.extended_syntax:
-                       if dep_getslot(x) is not None:
+                       if x.operator == '=*':
                                if maxvalue < 0:
                                        maxvalue = 0
                                        bestm = x
-                       else:
+                       elif x.slot is not None:
                                if maxvalue < -1:
                                        maxvalue = -1
                                        bestm = x
+                       else:
+                               if maxvalue < -2:
+                                       maxvalue = -2
+                                       bestm = x
                        continue
                if dep_getslot(x) is not None:
                        if maxvalue < 3:
@@ -2099,7 +2113,39 @@ def match_from_list(mydep, candidate_list):
 
        mylist = []
 
-       if operator is None:
+       if mydep.extended_syntax:
+
+               for x in candidate_list:
+                       cp = getattr(x, "cp", None)
+                       if cp is None:
+                               mysplit = catpkgsplit(remove_slot(x))
+                               if mysplit is not None:
+                                       cp = mysplit[0] + '/' + mysplit[1]
+
+                       if cp is None:
+                               continue
+
+                       if cp == mycpv or extended_cp_match(mydep.cp, cp):
+                               mylist.append(x)
+
+               if mylist and mydep.operator == "=*":
+
+                       candidate_list = mylist
+                       mylist = []
+                       # Currently, only \*\d+\* is supported.
+                       ver = mydep.version[1:-1]
+
+                       for x in candidate_list:
+                               x_ver = getattr(x, "version", None)
+                               if x_ver is None:
+                                       xs = catpkgsplit(remove_slot(x))
+                                       if xs is None:
+                                               continue
+                                       x_ver = "-".join(xs[-2:])
+                               if ver in x_ver:
+                                       mylist.append(x)
+
+       elif operator is None:
                for x in candidate_list:
                        cp = getattr(x, "cp", None)
                        if cp is None:
@@ -2110,8 +2156,7 @@ def match_from_list(mydep, candidate_list):
                        if cp is None:
                                continue
 
-                       if cp == mycpv or (mydep.extended_syntax and \
-                               extended_cp_match(mydep.cp, cp)):
+                       if cp == mydep.cp:
                                mylist.append(x)
 
        elif operator == "=": # Exact match
index e0cfaabcf95b9c793d451db19d2755a22882d3ef..f5a7d374971bb5232ad8d54625f4402376901c16 100644 (file)
@@ -20,6 +20,10 @@ class TestAtom(TestCase):
                                (None,  'sys-apps/portage', None, '0', '[doc]', None), False, False ),
                        ( "*/*",
                                (None,  '*/*', None, None, None, None), True, False ),
+                       ( "=*/*-*9999*",
+                               ('=*',  '*/*', '*9999*', None, None, None), True, False ),
+                       ( "=*/*-*9999*:0::repo_name",
+                               ('=*',  '*/*', '*9999*', '0', None, 'repo_name'), True, True ),
                        ( "sys-apps/*",
                                (None,  'sys-apps/*', None, None, None, None), True, False ),
                        ( "*/portage",
index 58ab95b0fa7ac428a4548ad4b1d820927fd5a81c..8a14038280b3070362ca789ae3e0185ae805cdfe 100644 (file)
@@ -38,6 +38,8 @@ class Test_best_match_to_list(TestCase):
                                                [Atom("=dev-libs/A-1:0")], True),
                                        ("dev-libs/A-1", [Atom("dev-libs/*", allow_wildcard=True), Atom("=dev-libs/A-1:0")], \
                                                [Atom("=dev-libs/A-1:0"), Atom("dev-libs/*", allow_wildcard=True)], True),
+                                       ("dev-libs/A-4.9999-r1", [Atom("dev-libs/*", allow_wildcard=True), Atom("=*/*-*9999*", allow_wildcard=True)], \
+                                               [Atom("=*/*-*9999*", allow_wildcard=True), Atom("dev-libs/*", allow_wildcard=True)], True),
                                        ("dev-libs/A-1:0", [Atom("dev-*/*", allow_wildcard=True), Atom("dev-*/*:0", allow_wildcard=True),\
                                                Atom("dev-libs/A"), Atom("<=dev-libs/A-2"), Atom("dev-libs/A:0"), \
                                                Atom("=dev-libs/A-1*"), Atom("~dev-libs/A-1"), Atom("=dev-libs/A-1")], \