blob: 6eaa223f662bf4543eb438be424c4d8c7fd3d047 [file] [log] [blame]
# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = ['getmaskingstatus']
import sys
import portage
from portage import eapi_is_supported, _eapi_is_deprecated
from portage.dep import match_from_list, _slot_separator, _repo_separator
from portage.localization import _
from portage.package.ebuild.config import config
from portage.versions import catpkgsplit, cpv_getkey
from _emerge.Package import Package
if sys.hexversion >= 0x3000000:
basestring = str
class _UnmaskHint(object):
__slots__ = ('key', 'value')
def __init__(self, key, value):
self.key = key
self.value = value
class _MaskReason(object):
__slots__ = ('category', 'message', 'unmask_hint')
def __init__(self, category, message, unmask_hint=None):
self.category = category
self.message = message
self.unmask_hint = unmask_hint
def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None):
if settings is None:
settings = config(clone=portage.settings)
if portdb is None:
portdb = portage.portdb
return [mreason.message for \
mreason in _getmaskingstatus(mycpv, settings, portdb,myrepo)]
def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):
metadata = None
installed = False
if not isinstance(mycpv, basestring):
# emerge passed in a Package instance
pkg = mycpv
mycpv = pkg.cpv
metadata = pkg.metadata
installed = pkg.installed
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
return [_MaskReason("corruption", "corruption")]
if "?" in metadata["LICENSE"]:
settings.setcpv(mycpv, mydb=metadata)
metadata["USE"] = settings["PORTAGE_USE"]
else:
metadata["USE"] = ""
rValue = []
# package.mask checking
if settings._getMaskAtom(mycpv, metadata):
rValue.append(_MaskReason("package.mask", "package.mask", _UnmaskHint("p_mask", None)))
# keywords checking
eapi = metadata["EAPI"]
mygroups = settings._getKeywords(mycpv, metadata)
licenses = metadata["LICENSE"]
properties = metadata["PROPERTIES"]
if eapi.startswith("-"):
eapi = eapi[1:]
if not eapi_is_supported(eapi):
return [_MaskReason("EAPI", "EAPI %s" % eapi)]
elif _eapi_is_deprecated(eapi) and not installed:
return [_MaskReason("EAPI", "EAPI %s" % eapi)]
egroups = settings.configdict["backupenv"].get(
"ACCEPT_KEYWORDS", "").split()
global_accept_keywords = settings.get("ACCEPT_KEYWORDS", "")
pgroups = global_accept_keywords.split()
myarch = settings["ARCH"]
if pgroups and myarch not in pgroups:
"""For operating systems other than Linux, ARCH is not necessarily a
valid keyword."""
myarch = pgroups[0].lstrip("~")
# NOTE: This logic is copied from KeywordsManager.getMissingKeywords().
unmaskgroups = settings._keywords_manager.getPKeywords(mycpv,
metadata["SLOT"], metadata["repository"], global_accept_keywords)
pgroups.extend(unmaskgroups)
if unmaskgroups or egroups:
pgroups = settings._keywords_manager._getEgroups(egroups, pgroups)
else:
pgroups = set(pgroups)
kmask = "missing"
kmask_hint = None
if '**' in pgroups:
kmask = None
else:
for keyword in pgroups:
if keyword in mygroups:
kmask = None
break
if kmask:
for gp in mygroups:
if gp=="*":
kmask=None
break
elif gp=="-"+myarch and myarch in pgroups:
kmask="-"+myarch
break
elif gp=="~"+myarch and myarch in pgroups:
kmask="~"+myarch
kmask_hint = _UnmaskHint("unstable keyword", kmask)
break
if kmask == "missing":
kmask_hint = _UnmaskHint("unstable keyword", "**")
try:
missing_licenses = settings._getMissingLicenses(mycpv, metadata)
if missing_licenses:
allowed_tokens = set(["||", "(", ")"])
allowed_tokens.update(missing_licenses)
license_split = licenses.split()
license_split = [x for x in license_split \
if x in allowed_tokens]
msg = license_split[:]
msg.append("license(s)")
rValue.append(_MaskReason("LICENSE", " ".join(msg), _UnmaskHint("license", set(missing_licenses))))
except portage.exception.InvalidDependString as e:
rValue.append(_MaskReason("invalid", "LICENSE: "+str(e)))
try:
missing_properties = settings._getMissingProperties(mycpv, metadata)
if missing_properties:
allowed_tokens = set(["||", "(", ")"])
allowed_tokens.update(missing_properties)
properties_split = properties.split()
properties_split = [x for x in properties_split \
if x in allowed_tokens]
msg = properties_split[:]
msg.append("properties")
rValue.append(_MaskReason("PROPERTIES", " ".join(msg)))
except portage.exception.InvalidDependString as e:
rValue.append(_MaskReason("invalid", "PROPERTIES: "+str(e)))
# Only show KEYWORDS masks for installed packages
# if they're not masked for any other reason.
if kmask and (not installed or not rValue):
rValue.append(_MaskReason("KEYWORDS",
kmask + " keyword", unmask_hint=kmask_hint))
return rValue