1 # Copyright 2010 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 __all__ = ['getmaskingstatus']
9 from portage import eapi_is_supported, _eapi_is_deprecated
10 from portage.dep import match_from_list, _slot_separator, _repo_separator
11 from portage.localization import _
12 from portage.package.ebuild.config import config
13 from portage.versions import catpkgsplit, cpv_getkey
15 if sys.hexversion >= 0x3000000:
18 class _UnmaskHint(object):
20 __slots__ = ('key', 'value')
22 def __init__(self, key, value):
26 class _MaskReason(object):
28 __slots__ = ('category', 'message', 'unmask_hint')
30 def __init__(self, category, message, unmask_hint=None):
31 self.category = category
32 self.message = message
33 self.unmask_hint = unmask_hint
35 def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None):
37 settings = config(clone=portage.settings)
39 portdb = portage.portdb
41 return [mreason.message for \
42 mreason in _getmaskingstatus(mycpv, settings, portdb,myrepo)]
44 def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):
48 if not isinstance(mycpv, basestring):
49 # emerge passed in a Package instance
52 metadata = pkg.metadata
53 installed = pkg.installed
55 mysplit = catpkgsplit(mycpv)
57 raise ValueError(_("invalid CPV: %s") % mycpv)
59 db_keys = list(portdb._aux_cache_keys)
61 metadata = dict(zip(db_keys, portdb.aux_get(mycpv, db_keys, myrepo=myrepo)))
63 if not portdb.cpv_exists(mycpv):
65 return [_MaskReason("corruption", "corruption")]
66 if "?" in metadata["LICENSE"]:
67 settings.setcpv(mycpv, mydb=metadata)
68 metadata["USE"] = settings["PORTAGE_USE"]
75 if settings._getProfileMaskAtom(mycpv, metadata):
76 rValue.append(_MaskReason("profile", "profile"))
78 # package.mask checking
79 if settings._getMaskAtom(mycpv, metadata):
80 rValue.append(_MaskReason("package.mask", "package.mask", _UnmaskHint("p_mask", None)))
83 eapi = metadata["EAPI"]
84 mygroups = settings._getKeywords(mycpv, metadata)
85 licenses = metadata["LICENSE"]
86 properties = metadata["PROPERTIES"]
87 if eapi.startswith("-"):
89 if not eapi_is_supported(eapi):
90 return [_MaskReason("EAPI", "EAPI %s" % eapi)]
91 elif _eapi_is_deprecated(eapi) and not installed:
92 return [_MaskReason("EAPI", "EAPI %s" % eapi)]
93 egroups = settings.configdict["backupenv"].get(
94 "ACCEPT_KEYWORDS", "").split()
95 pgroups = settings["ACCEPT_KEYWORDS"].split()
96 myarch = settings["ARCH"]
97 if pgroups and myarch not in pgroups:
98 """For operating systems other than Linux, ARCH is not necessarily a
100 myarch = pgroups[0].lstrip("~")
102 cp = cpv_getkey(mycpv)
103 pkgdict = settings._keywords_manager.pkeywordsdict.get(cp)
106 pkg = "".join((mycpv, _slot_separator, metadata["SLOT"]))
107 if 'repository' in metadata:
108 pkg = "".join((pkg, _repo_separator, metadata['repository']))
109 cpv_slot_list = [pkg]
110 for atom, pkgkeywords in pkgdict.items():
111 if match_from_list(atom, cpv_slot_list):
113 pgroups.extend(pkgkeywords)
114 if matches or egroups:
115 pgroups.extend(egroups)
118 if x.startswith("-"):
122 inc_pgroups.discard(x[1:])
125 pgroups = inc_pgroups
134 for keyword in pgroups:
135 if keyword in mygroups:
144 elif gp=="-"+myarch and myarch in pgroups:
147 elif gp=="~"+myarch and myarch in pgroups:
149 kmask_hint = _UnmaskHint("unstable keyword", kmask)
153 missing_licenses = settings._getMissingLicenses(mycpv, metadata)
155 allowed_tokens = set(["||", "(", ")"])
156 allowed_tokens.update(missing_licenses)
157 license_split = licenses.split()
158 license_split = [x for x in license_split \
159 if x in allowed_tokens]
160 msg = license_split[:]
161 msg.append("license(s)")
162 rValue.append(_MaskReason("LICENSE", " ".join(msg), _UnmaskHint("license", set(missing_licenses))))
163 except portage.exception.InvalidDependString as e:
164 rValue.append(_MaskReason("invalid", "LICENSE: "+str(e)))
167 missing_properties = settings._getMissingProperties(mycpv, metadata)
168 if missing_properties:
169 allowed_tokens = set(["||", "(", ")"])
170 allowed_tokens.update(missing_properties)
171 properties_split = properties.split()
172 properties_split = [x for x in properties_split \
173 if x in allowed_tokens]
174 msg = properties_split[:]
175 msg.append("properties")
176 rValue.append(_MaskReason("PROPERTIES", " ".join(msg)))
177 except portage.exception.InvalidDependString as e:
178 rValue.append(_MaskReason("invalid", "PROPERTIES: "+str(e)))
180 # Only show KEYWORDS masks for installed packages
181 # if they're not masked for any other reason.
182 if kmask and (not installed or not rValue):
183 rValue.append(_MaskReason("KEYWORDS",
184 kmask + " keyword", unmask_hint=kmask_hint))