split up the getMissingKeywords code to eliminate code duplication and increase flexi...
authorBrian Dolbec <brian.dolbec@gmail.com>
Sun, 30 Jan 2011 20:39:39 +0000 (12:39 -0800)
committerZac Medico <zmedico@gentoo.org>
Sun, 30 Jan 2011 22:37:48 +0000 (14:37 -0800)
pym/portage/package/ebuild/_config/KeywordsManager.py

index bff7afa781e490baa1a3b8bf8db13c39da8ca2fe..8a6b4bd6e2fdb8f9b970b5477b3ce2d1ec6f1496 100644 (file)
@@ -13,11 +13,14 @@ from portage.util import grabdict_package, stack_lists, writemsg
 from portage.versions import cpv_getkey
 
 class KeywordsManager(object):
+       """Manager class to handle keywords processing and validation"""
 
-       def __init__(self, profiles, abs_user_config, user_config=True, global_accept_keywords=""):
+       def __init__(self, profiles, abs_user_config, user_config=True,
+                               global_accept_keywords=""):
                self._pkeywords_list = []
                rawpkeywords = [grabdict_package(
-                       os.path.join(x, "package.keywords"), recursive=1, verify_eapi=True) \
+                       os.path.join(x, "package.keywords"), recursive=1,
+                       verify_eapi=True) \
                        for x in profiles]
                for pkeyworddict in rawpkeywords:
                        if not pkeyworddict:
@@ -31,7 +34,8 @@ class KeywordsManager(object):
 
                self._p_accept_keywords = []
                raw_p_accept_keywords = [grabdict_package(
-                       os.path.join(x, "package.accept_keywords"), recursive=1, verify_eapi=True) \
+                       os.path.join(x, "package.accept_keywords"), recursive=1,
+                       verify_eapi=True) \
                        for x in profiles]
                for d in raw_p_accept_keywords:
                        if not d:
@@ -48,11 +52,13 @@ class KeywordsManager(object):
                if user_config:
                        pkgdict = grabdict_package(
                                os.path.join(abs_user_config, "package.keywords"),
-                               recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False)
+                               recursive=1, allow_wildcard=True, allow_repo=True,
+                               verify_eapi=False)
 
                        for k, v in grabdict_package(
                                os.path.join(abs_user_config, "package.accept_keywords"),
-                               recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False).items():
+                               recursive=1, allow_wildcard=True, allow_repo=True,
+                               verify_eapi=False).items():
                                pkgdict.setdefault(k, []).extend(v)
 
                        accept_keywords_defaults = global_accept_keywords.split()
@@ -66,6 +72,7 @@ class KeywordsManager(object):
                                        v = tuple(v)
                                self.pkeywordsdict.setdefault(k.cp, {})[k] = v
 
+
        def getKeywords(self, cpv, slot, keywords, repo):
                cp = cpv_getkey(cpv)
                pkg = "".join((cpv, _slot_separator, slot))
@@ -80,7 +87,14 @@ class KeywordsManager(object):
                                        keywords.extend(pkg_keywords)
                return stack_lists(keywords, incremental=True)
 
-       def getMissingKeywords(self, cpv, slot, keywords, repo, global_accept_keywords, backuped_accept_keywords):
+
+       def getMissingKeywords(self,
+                                                       cpv,
+                                                       slot,
+                                                       keywords,
+                                                       repo,
+                                                       global_accept_keywords,
+                                                       backuped_accept_keywords):
                """
                Take a package and return a list of any KEYWORDS that the user may
                need to accept for the given package. If the KEYWORDS are empty
@@ -102,88 +116,30 @@ class KeywordsManager(object):
                @return: A list of KEYWORDS that have not been accepted.
                """
 
-               # Hack: Need to check the env directly here as otherwise stacking
-               # doesn't work properly as negative values are lost in the config
-               # object (bug #139600)
-               egroups = backuped_accept_keywords.split()
                mygroups = self.getKeywords(cpv, slot, keywords, repo)
                # Repoman may modify this attribute as necessary.
                pgroups = global_accept_keywords.split()
-               matches = False
-               cp = cpv_getkey(cpv)
 
-               if self._p_accept_keywords:
-                       cpv_slot = "%s:%s" % (cpv, slot)
-                       accept_keywords_defaults = tuple('~' + keyword for keyword in \
-                               pgroups if keyword[:1] not in "~-")
-                       for d in self._p_accept_keywords:
-                               cpdict = d.get(cp)
-                               if cpdict:
-                                       pkg_accept_keywords = \
-                                               ordered_by_atom_specificity(cpdict, cpv_slot)
-                                       if pkg_accept_keywords:
-                                               for x in pkg_accept_keywords:
-                                                       if not x:
-                                                               x = accept_keywords_defaults
-                                                       pgroups.extend(x)
-                                               matches = True
+               unmaskgroups = self.getPKeywords(cpv, slot, repo,
+                               global_accept_keywords)
+               pgroups.extend(unmaskgroups)
 
-               pkgdict = self.pkeywordsdict.get(cp)
-               if pkgdict:
-                       cpv_slot = "%s:%s" % (cpv, slot)
-                       pkg_accept_keywords = \
-                               ordered_by_atom_specificity(pkgdict, cpv_slot, repo=repo)
-                       if pkg_accept_keywords:
-                               for x in pkg_accept_keywords:
-                                       pgroups.extend(x)
-                               matches = True
+               # Hack: Need to check the env directly here as otherwise stacking
+               # doesn't work properly as negative values are lost in the config
+               # object (bug #139600)
+               egroups = self._getEgroups(backuped_accept_keywords)
+               pgroups.extend(egroups)
 
-               if matches or egroups:
-                       pgroups.extend(egroups)
-                       inc_pgroups = set()
-                       for x in pgroups:
-                               if x.startswith("-"):
-                                       if x == "-*":
-                                               inc_pgroups.clear()
-                                       else:
-                                               inc_pgroups.discard(x[1:])
-                               else:
-                                       inc_pgroups.add(x)
-                       pgroups = inc_pgroups
-                       del inc_pgroups
+               return self._getMissingKeywords(cpv, pgroups, mygroups)
 
-               match = False
-               hasstable = False
-               hastesting = False
-               for gp in mygroups:
-                       if gp == "*" or (gp == "-*" and len(mygroups) == 1):
-                               writemsg(_("--- WARNING: Package '%(cpv)s' uses"
-                                       " '%(keyword)s' keyword.\n") % {"cpv": cpv, "keyword": gp}, noiselevel=-1)
-                               if gp == "*":
-                                       match = 1
-                                       break
-                       elif gp in pgroups:
-                               match=1
-                               break
-                       elif gp.startswith("~"):
-                               hastesting = True
-                       elif not gp.startswith("-"):
-                               hasstable = True
-               if not match and \
-                       ((hastesting and "~*" in pgroups) or \
-                       (hasstable and "*" in pgroups) or "**" in pgroups):
-                       match=1
-               if match:
-                       missing = []
-               else:
-                       if not mygroups:
-                               # If KEYWORDS is empty then we still have to return something
-                               # in order to distinguish from the case of "none missing".
-                               mygroups.append("**")
-                       missing = mygroups
-               return missing
 
-       def getRawMissingKeywords(self, cpv, slot, keywords, repo, global_accept_keywords, backuped_accept_keywords):
+       def getRawMissingKeywords(self,
+                                                       cpv,
+                                                       slot,
+                                                       keywords,
+                                                       repo,
+                                                       global_accept_keywords,
+                                                       backuped_accept_keywords):
                """
                Take a package and return a list of any KEYWORDS that the user may
                need to accept for the given package. If the KEYWORDS are empty,
@@ -206,18 +162,37 @@ class KeywordsManager(object):
                and the keywords it looked for.
                """
 
-               # Hack: Need to check the env directly here as otherwise stacking
-               # doesn't work properly as negative values are lost in the config
-               # object (bug #139600)
-               egroups = backuped_accept_keywords.split()
                mygroups = self.getKeywords(cpv, slot, keywords, repo)
                # Repoman may modify this attribute as necessary.
                pgroups = global_accept_keywords.split()
-               matches = False
 
-               ## we want to use the environment keywords here,
-               ## but stripped to it's base arch
-               ## we want the raw keywords needed to be accepted from the ebuild
+               # Hack: Need to check the env directly here as otherwise stacking
+               # doesn't work properly as negative values are lost in the config
+               # object (bug #139600)
+               # we want to use the environment keywords here,
+               # but stripped to it's base arch
+               # we want the raw keywords needed to be accepted from the ebuild
+               egroups = self._getEgroups(backuped_accept_keywords)
+               egroups = [x.lstrip('~') for x in egroups]
+
+               pgroups.extend(egroups)
+
+               missing = self._getMissingKeywords(cpv, pgroups, mygroups)
+
+               return missing, pgroups
+
+
+       @staticmethod
+       def _getEgroups(backuped_accept_keywords):
+               """gets any keywords defined in the environment
+
+               @param backuped_accept_keywords: ACCEPT_KEYWORDS from the backup env
+               @type backuped_accept_keywords: String
+               @rtype: List
+               @return: list of KEYWORDS that have been accepted
+               """
+               egroups = backuped_accept_keywords.split()
+               pgroups = []
                if egroups:
                        pgroups.extend(egroups)
                        inc_pgroups = set()
@@ -228,22 +203,34 @@ class KeywordsManager(object):
                                        else:
                                                inc_pgroups.discard(x[1:])
                                else:
-                                       inc_pgroups.add(x.lstrip('~'))
+                                       inc_pgroups.add(x)
                        pgroups = inc_pgroups
                        del inc_pgroups
+               return pgroups
+
 
+       @staticmethod
+       def _getMissingKeywords(cpv, pgroups, mygroups):
+               """Determines the missing keywords
+
+               @param pgroups: The pkg keywords accepted
+               @type pgroups: list
+               @param mygroups: The ebuild keywords
+               @type mygroups: list
+               """
                match = False
                hasstable = False
                hastesting = False
                for gp in mygroups:
                        if gp == "*" or (gp == "-*" and len(mygroups) == 1):
                                writemsg(_("--- WARNING: Package '%(cpv)s' uses"
-                                       " '%(keyword)s' keyword.\n") % {"cpv": cpv, "keyword": gp}, noiselevel=-1)
+                                       " '%(keyword)s' keyword.\n") % {"cpv": cpv, "keyword": gp},
+                                        noiselevel=-1)
                                if gp == "*":
-                                       match = 1
+                                       match = True
                                        break
                        elif gp in pgroups:
-                               match=1
+                               match = True
                                break
                        elif gp.startswith("~"):
                                hastesting = True
@@ -252,7 +239,7 @@ class KeywordsManager(object):
                if not match and \
                        ((hastesting and "~*" in pgroups) or \
                        (hasstable and "*" in pgroups) or "**" in pgroups):
-                       match=1
+                       match = True
                if match:
                        missing = []
                else:
@@ -261,4 +248,53 @@ class KeywordsManager(object):
                                # in order to distinguish from the case of "none missing".
                                mygroups.append("**")
                        missing = mygroups
-               return missing, pgroups
+               return missing
+
+
+       def getPKeywords(self, cpv, slot, repo, global_accept_keywords):
+               """Gets any package.keywords settings for cp for the given
+               cpv, slot and repo
+
+               @param cpv: The package name (for package.keywords support)
+               @type cpv: String
+               @param slot: The 'SLOT' key from the raw package metadata
+               @type slot: String
+               @param keywords: The 'KEYWORDS' key from the raw package metadata
+               @type keywords: String
+               @param global_accept_keywords: The current value of ACCEPT_KEYWORDS
+               @type global_accept_keywords: String
+               @param backuped_accept_keywords: ACCEPT_KEYWORDS from the backup env
+               @type backuped_accept_keywords: String
+               @rtype: List
+               @return: list of KEYWORDS that have been accepted
+               """
+
+               pgroups = global_accept_keywords.split()
+               cp = cpv_getkey(cpv)
+
+               unmaskgroups = []
+               if self._p_accept_keywords:
+                       cpv_slot = "%s:%s" % (cpv, slot)
+                       accept_keywords_defaults = tuple('~' + keyword for keyword in \
+                               pgroups if keyword[:1] not in "~-")
+                       for d in self._p_accept_keywords:
+                               cpdict = d.get(cp)
+                               if cpdict:
+                                       pkg_accept_keywords = \
+                                               ordered_by_atom_specificity(cpdict, cpv_slot)
+                                       if pkg_accept_keywords:
+                                               for x in pkg_accept_keywords:
+                                                       if not x:
+                                                               x = accept_keywords_defaults
+                                                       unmaskgroups.extend(x)
+
+               pkgdict = self.pkeywordsdict.get(cp)
+               if pkgdict:
+                       cpv_slot = "%s:%s" % (cpv, slot)
+                       pkg_accept_keywords = \
+                               ordered_by_atom_specificity(pkgdict, cpv_slot, repo=repo)
+                       if pkg_accept_keywords:
+                               for x in pkg_accept_keywords:
+                                       unmaskgroups.extend(x)
+               return unmaskgroups
+