diff options
Diffstat (limited to 'pym/portage/package')
-rw-r--r-- | pym/portage/package/ebuild/config.py | 158 | ||||
-rw-r--r-- | pym/portage/package/ebuild/doebuild.py | 2 | ||||
-rw-r--r-- | pym/portage/package/ebuild/getmaskingstatus.py | 37 |
3 files changed, 137 insertions, 60 deletions
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 2ffad468..4f5f9413 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -843,12 +843,8 @@ class config(object): else: self.configdict["conf"]["ACCEPT_LICENSE"] = " ".join(v) for k, v in licdict.items(): - cp = k.cp - cp_dict = self._plicensedict.get(cp) - if not cp_dict: - cp_dict = {} - self._plicensedict[cp] = cp_dict - cp_dict[k] = self.expandLicenseTokens(v) + self._plicensedict.setdefault(k.cp, {})[k] = \ + self.expandLicenseTokens(v) #package.properties propdict = grabdict_package(os.path.join( @@ -860,12 +856,7 @@ class config(object): else: self.configdict["conf"]["ACCEPT_PROPERTIES"] = " ".join(v) for k, v in propdict.items(): - cp = k.cp - cp_dict = self._ppropertiesdict.get(cp) - if not cp_dict: - cp_dict = {} - self._ppropertiesdict[cp] = cp_dict - cp_dict[k] = v + self._ppropertiesdict.setdefault(k.cp, {})[k] = v #getting categories from an external file now categories = [grabfile(os.path.join(x, "categories")) for x in locations] @@ -1425,22 +1416,24 @@ class config(object): has_changed = True defaults = [] - pos = 0 for i, pkgprofileuse_dict in enumerate(self.pkgprofileuse): + if self.make_defaults_use[i]: + defaults.append(self.make_defaults_use[i]) cpdict = pkgprofileuse_dict.get(cp) if cpdict: + pkg_defaults = [] keys = list(cpdict) while keys: bestmatch = best_match_to_list(cpv_slot, keys) if bestmatch: keys.remove(bestmatch) - defaults.insert(pos, cpdict[bestmatch]) + pkg_defaults.append(cpdict[bestmatch]) else: break - del keys - if self.make_defaults_use[i]: - defaults.insert(pos, self.make_defaults_use[i]) - pos = len(defaults) + if pkg_defaults: + # reverse, so the most specific atoms come last + pkg_defaults.reverse() + defaults.extend(pkg_defaults) defaults = " ".join(defaults) if defaults != self.configdict["defaults"].get("USE",""): self.configdict["defaults"]["USE"] = defaults @@ -1614,22 +1607,24 @@ class config(object): if cp is None: cp = cpv_getkey(remove_slot(pkg)) usemask = [] - pos = 0 for i, pusemask_dict in enumerate(self.pusemask_list): + if self.usemask_list[i]: + usemask.append(self.usemask_list[i]) cpdict = pusemask_dict.get(cp) if cpdict: + pkg_usemask = [] keys = list(cpdict) while keys: best_match = best_match_to_list(pkg, keys) if best_match: keys.remove(best_match) - usemask.insert(pos, cpdict[best_match]) + pkg_usemask.append(cpdict[best_match]) else: break - del keys - if self.usemask_list[i]: - usemask.insert(pos, self.usemask_list[i]) - pos = len(usemask) + if pkg_usemask: + # reverse, so the most specific atoms come last + pkg_usemask.reverse() + usemask.extend(pkg_usemask) return set(stack_lists(usemask, incremental=True)) def _getUseForce(self, pkg): @@ -1637,22 +1632,24 @@ class config(object): if cp is None: cp = cpv_getkey(remove_slot(pkg)) useforce = [] - pos = 0 for i, puseforce_dict in enumerate(self.puseforce_list): + if self.useforce_list[i]: + useforce.append(self.useforce_list[i]) cpdict = puseforce_dict.get(cp) if cpdict: + pkg_useforce = [] keys = list(cpdict) while keys: best_match = best_match_to_list(pkg, keys) if best_match: keys.remove(best_match) - useforce.insert(pos, cpdict[best_match]) + pkg_useforce.append(cpdict[best_match]) else: break - del keys - if self.useforce_list[i]: - useforce.insert(pos, self.useforce_list[i]) - pos = len(useforce) + if pkg_useforce: + # reverse, so the most specific atoms come last + pkg_useforce.reverse() + useforce.extend(pkg_useforce) return set(stack_lists(useforce, incremental=True)) def _getMaskAtom(self, cpv, metadata): @@ -1721,19 +1718,22 @@ class config(object): if 'repository' in metadata: pkg = "".join((pkg, _repo_separator, metadata['repository'])) keywords = [[x for x in metadata["KEYWORDS"].split() if x != "-*"]] - pos = len(keywords) for pkeywords_dict in self._pkeywords_list: cpdict = pkeywords_dict.get(cp) if cpdict: + pkg_keywords = [] keys = list(cpdict) while keys: best_match = best_match_to_list(pkg, keys) if best_match: keys.remove(best_match) - keywords.insert(pos, cpdict[best_match]) + pkg_keywords.append(cpdict[best_match]) else: break - pos = len(keywords) + if pkg_keywords: + # reverse, so the most specific atoms come last + pkg_keywords.reverse() + keywords.extend(pkg_keywords) return stack_lists(keywords, incremental=True) def _getMissingKeywords(self, cpv, metadata): @@ -1765,14 +1765,24 @@ class config(object): pkgdict = self.pkeywordsdict.get(cp) matches = False if pkgdict: - pkg = "".join((cpv, _slot_separator, metadata["SLOT"])) + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) if 'repository' in metadata: - pkg = "".join((pkg, _repo_separator, metadata['repository'])) - cpv_slot_list = [pkg] - for atom, pkgkeywords in pkgdict.items(): - if match_from_list(atom, cpv_slot_list): - matches = True - pgroups.extend(pkgkeywords) + cpv_slot = "".join((cpv_slot, _repo_separator, metadata['repository'])) + pkg_accept_keywords = [] + keys = list(pkgdict) + while keys: + best_match = best_match_to_list(cpv_slot, keys) + if best_match: + keys.remove(best_match) + pkg_accept_keywords.append(pkgdict[best_match]) + else: + break + if pkg_accept_keywords: + # reverse, so the most specific atoms come last + pkg_accept_keywords.reverse() + for x in pkg_accept_keywords: + pgroups.extend(x) + matches = True if matches or egroups: pgroups.extend(egroups) inc_pgroups = set() @@ -1834,12 +1844,24 @@ class config(object): cp = cpv_getkey(cpv) cpdict = self._plicensedict.get(cp) if cpdict: - accept_license = list(self._accept_license) - cpv_slot = "".join((cpv, _slot_separator, metadata["SLOT"])) + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) if 'repository' in metadata: cpv_slot = "".join((cpv_slot, _repo_separator, metadata['repository'])) - for atom in match_to_list(cpv_slot, list(cpdict)): - accept_license.extend(cpdict[atom]) + keys = list(cpdict) + plicence_list = [] + while keys: + bestmatch = best_match_to_list(cpv_slot, keys) + if bestmatch: + keys.remove(bestmatch) + plicence_list.append(cpdict[bestmatch]) + else: + break + if plicence_list: + # reverse, so the most specific atoms come last + plicence_list.reverse() + accept_license = list(self._accept_license) + for x in plicence_list: + accept_license.extend(x) licenses = set(flatten(use_reduce(paren_reduce( metadata["LICENSE"]), matchall=1))) @@ -1916,12 +1938,24 @@ class config(object): cp = cpv_getkey(cpv) cpdict = self._ppropertiesdict.get(cp) if cpdict: - accept_properties = list(self._accept_properties) - cpv_slot = "".join((cpv, _slot_separator, metadata["SLOT"])) + cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) if 'repository' in metadata: cpv_slot = "".join((cpv_slot, _repo_separator, metadata['repository'])) - for atom in match_to_list(cpv_slot, list(cpdict)): - accept_properties.extend(cpdict[atom]) + keys = list(cpdict) + pproperties_list = [] + while keys: + bestmatch = best_match_to_list(cpv_slot, keys) + if bestmatch: + keys.remove(bestmatch) + pproperties_list.append(cpdict[bestmatch]) + else: + break + if pproperties_list: + # reverse, so the most specific atoms come last + pproperties_list.reverse() + accept_properties = list(self._accept_properties) + for x in pproperties_list: + accept_properties.extend(x) properties = set(flatten(use_reduce(paren_reduce( metadata["PROPERTIES"]), matchall=1))) @@ -2228,6 +2262,9 @@ class config(object): # For optimal performance, use slice # comparison instead of startswith(). + iuse = self.configdict["pkg"].get("IUSE") + if iuse is not None: + iuse = [x.lstrip("+-") for x in iuse.split()] myflags = set() for curdb in self.uvlist: cur_use_expand = [x for x in use_expand if x in curdb] @@ -2247,10 +2284,33 @@ class config(object): continue if x[0] == "-": + if x[-2:] == '_*': + prefix = x[1:-1] + prefix_len = len(prefix) + myflags.difference_update( + [y for y in myflags if \ + y[:prefix_len] == prefix]) myflags.discard(x[1:]) continue - myflags.add(x) + if iuse is not None and x[-2:] == '_*': + # Expand wildcards here, so that cases like + # USE="linguas_* -linguas_en_US" work correctly. + prefix = x[:-1] + prefix_len = len(prefix) + has_iuse = False + for y in iuse: + if y[:prefix_len] == prefix: + has_iuse = True + myflags.add(y) + if not has_iuse: + # There are no matching IUSE, so allow the + # wildcard to pass through. This allows + # linguas_* to trigger unset LINGUAS in + # cases when no linguas_ flags are in IUSE. + myflags.add(x) + else: + myflags.add(x) for var in cur_use_expand: var_lower = var.lower() diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 78d1360c..afffd45d 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -1268,7 +1268,7 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero buf = array.array('B') try: buf.fromfile(f, buffsize) - except EOFError: + except (EOFError, IOError): pass if not buf: eof = True diff --git a/pym/portage/package/ebuild/getmaskingstatus.py b/pym/portage/package/ebuild/getmaskingstatus.py index 8fbbff02..5e5a13f1 100644 --- a/pym/portage/package/ebuild/getmaskingstatus.py +++ b/pym/portage/package/ebuild/getmaskingstatus.py @@ -15,12 +15,26 @@ from portage.versions import catpkgsplit, cpv_getkey if sys.hexversion >= 0x3000000: basestring = str +class _MaskReason(object): + + __slots__ = ('category', 'message', 'hint') + + def __init__(self, category, message, hint=None): + self.category = category + self.message = message + self.hint = 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): @@ -40,7 +54,7 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): except KeyError: if not portdb.cpv_exists(mycpv): raise - return ["corruption"] + return [_MaskReason("corruption", "corruption")] if "?" in metadata["LICENSE"]: settings.setcpv(mycpv, mydb=metadata) metadata["USE"] = settings["PORTAGE_USE"] @@ -51,11 +65,11 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): # profile checking if settings._getProfileMaskAtom(mycpv, metadata): - rValue.append("profile") + rValue.append(_MaskReason("profile", "profile")) # package.mask checking if settings._getMaskAtom(mycpv, metadata): - rValue.append("package.mask") + rValue.append(_MaskReason("package.mask", "package.mask")) # keywords checking eapi = metadata["EAPI"] @@ -65,9 +79,9 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): if eapi.startswith("-"): eapi = eapi[1:] if not eapi_is_supported(eapi): - return ["EAPI %s" % eapi] + return [_MaskReason("EAPI", "EAPI %s" % eapi)] elif _eapi_is_deprecated(eapi) and not installed: - return ["EAPI %s" % eapi] + return [_MaskReason("EAPI", "EAPI %s" % eapi)] egroups = settings.configdict["backupenv"].get( "ACCEPT_KEYWORDS", "").split() pgroups = settings["ACCEPT_KEYWORDS"].split() @@ -104,6 +118,7 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): del inc_pgroups kmask = "missing" + kmask_hint = None if '**' in pgroups: kmask = None @@ -123,6 +138,7 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): break elif gp=="~"+myarch and myarch in pgroups: kmask="~"+myarch + kmask_hint = "unstable keyword" break try: @@ -135,9 +151,9 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): if x in allowed_tokens] msg = license_split[:] msg.append("license(s)") - rValue.append(" ".join(msg)) + rValue.append(_MaskReason("LICENSE", " ".join(msg))) except portage.exception.InvalidDependString as e: - rValue.append("LICENSE: "+str(e)) + rValue.append(_MaskReason("invalid", "LICENSE: "+str(e))) try: missing_properties = settings._getMissingProperties(mycpv, metadata) @@ -149,13 +165,14 @@ def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None): if x in allowed_tokens] msg = properties_split[:] msg.append("properties") - rValue.append(" ".join(msg)) + rValue.append(_MaskReason("PROPERTIES", " ".join(msg))) except portage.exception.InvalidDependString as e: - rValue.append("PROPERTIES: "+str(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(kmask+" keyword") + rValue.append(_MaskReason("KEYWORDS", + kmask + " keyword", hint=kmask_hint)) return rValue |