blob: 1e4ed21ceb387ba7356a29a1f0819d832d8895d1 [file] [log] [blame]
# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = ['getmaskingreason']
import portage
from portage import os
from portage.const import USER_CONFIG_PATH
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, _pkg_str
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:
portdb = portage.portdb
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, myrepo=myrepo)))
except KeyError:
if not portdb.cpv_exists(mycpv):
raise
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
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)
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")
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:
for x in pmaskdict[mycp]:
if match_from_list(x, cpv_slot_list):
x = x.without_repo
for pmask in pmasklists:
comment = ""
comment_valid = -1
pmask_filename = pmask[0]
for i in range(len(pmask[1])):
l = pmask[1][i].strip()
try:
l_atom = Atom(l, allow_repo=True,
allow_wildcard=True).without_repo
except InvalidAtom:
l_atom = None
if l == "":
comment = ""
comment_valid = -1
elif l[0] == "#":
comment += (l+"\n")
comment_valid = i + 1
elif l_atom == x:
if comment_valid != i:
comment = ""
if return_location:
return (comment, pmask_filename)
else:
return comment
elif comment_valid != -1:
# Apparently this comment applies to multiple masks, so
# it remains valid until a blank line is encountered.
comment_valid += 1
if return_location:
return (None, None)
else:
return None