getmaskingreason: handle UNKNOWN_REPO
[portage.git] / pym / portage / package / ebuild / getmaskingreason.py
index 6a0cf424cb434649d26c44272ec67bd7125de47e..70a6bf2e611675055da15984eb4d12e8f849dfb4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2013 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 __all__ = ['getmaskingreason']
@@ -6,13 +6,21 @@ __all__ = ['getmaskingreason']
 import portage
 from portage import os
 from portage.const import USER_CONFIG_PATH
-from portage.dep import Atom, match_from_list, _slot_separator, _repo_separator
+from portage.dep import Atom, match_from_list
 from portage.exception import InvalidAtom
 from portage.localization import _
+from portage.repository.config import _gen_valid_repo
 from portage.util import grablines, normalize_path
-from portage.versions import catpkgsplit
+from portage.versions import catpkgsplit, _pkg_str
 
-def getmaskingreason(mycpv, metadata=None, settings=None, portdb=None, return_location=False):
+def getmaskingreason(mycpv, metadata=None, settings=None,
+       portdb=None, return_location=False, myrepo=None):
+       """
+       If specified, the myrepo argument is assumed to be valid. This
+       should be a safe assumption since portdbapi methods always
+       return valid repo names and valid "repository" metadata from
+       aux_get.
+       """
        if settings is None:
                settings = portage.settings
        if portdb is None:
@@ -20,37 +28,64 @@ def getmaskingreason(mycpv, metadata=None, settings=None, portdb=None, return_lo
        mysplit = catpkgsplit(mycpv)
        if not mysplit:
                raise ValueError(_("invalid CPV: %s") % mycpv)
+
        if metadata is None:
                db_keys = list(portdb._aux_cache_keys)
                try:
-                       metadata = dict(zip(db_keys, portdb.aux_get(mycpv, db_keys)))
+                       metadata = dict(zip(db_keys,
+                               portdb.aux_get(mycpv, db_keys, myrepo=myrepo)))
                except KeyError:
                        if not portdb.cpv_exists(mycpv):
                                raise
-       if metadata is None:
-               # Can't access SLOT due to corruption.
-               cpv_slot_list = [mycpv]
-       else:
-               pkg = "".join((mycpv, _slot_separator, metadata["SLOT"]))
-               if 'repository' in metadata:
-                       pkg = "".join((pkg, _repo_separator, metadata['repository']))
-               cpv_slot_list = [pkg]
-       mycp=mysplit[0]+"/"+mysplit[1]
+               else:
+                       if myrepo is None:
+                               myrepo = _gen_valid_repo(metadata["repository"])
+
+       elif myrepo is None:
+               myrepo = metadata.get("repository")
+               if myrepo is not None:
+                       myrepo = _gen_valid_repo(metadata["repository"])
+
+       if metadata is not None and \
+               not portage.eapi_is_supported(metadata["EAPI"]):
+               # Return early since otherwise we might produce invalid
+               # results given that the EAPI is not supported. Also,
+               # metadata is mostly useless in this case since it doesn't
+               # contain essential things like SLOT.
+               if return_location:
+                       return (None, None)
+               else:
+                       return None
+
+       # Sometimes we can't access SLOT or repository due to corruption.
+       pkg = mycpv
+       try:
+               pkg.slot
+       except AttributeError:
+               pkg = _pkg_str(mycpv, metadata=metadata, repo=myrepo)
+
+       cpv_slot_list = [pkg]
+
+       mycp = pkg.cp
 
-       # XXX- This is a temporary duplicate of code from the config constructor.
-       locations = [os.path.join(settings["PORTDIR"], "profiles")]
+       locations = []
+       if pkg.repo in settings.repositories:
+               for repo in settings.repositories[pkg.repo].masters + (settings.repositories[pkg.repo],):
+                       locations.append(os.path.join(repo.location, "profiles"))
        locations.extend(settings.profiles)
-       for ov in settings["PORTDIR_OVERLAY"].split():
-               profdir = os.path.join(normalize_path(ov), "profiles")
-               if os.path.isdir(profdir):
-                       locations.append(profdir)
        locations.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
                USER_CONFIG_PATH))
        locations.reverse()
        pmasklists = []
        for profile in locations:
                pmask_filename = os.path.join(profile, "package.mask")
-               pmasklists.append((pmask_filename, grablines(pmask_filename, recursive=1)))
+               node = None
+               for l, recursive_filename in grablines(pmask_filename,
+                       recursive=1, remember_source_file=True):
+                       if node is None or node[0] != recursive_filename:
+                               node = (recursive_filename, [])
+                               pmasklists.append(node)
+                       node[1].append(l)
 
        pmaskdict = settings._mask_manager._pmaskdict
        if mycp in pmaskdict: