From: Fabian Groffen Date: Thu, 26 Oct 2006 17:40:15 +0000 (-0000) Subject: Merged from trunk 4816:4828 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=85ed9c9eb0cb010bf7e7bcb97debe27530da0e36;p=portage.git Merged from trunk 4816:4828 For bug #152726, ignore hidden files in vardbapi.cp_list(). For full compatibility with older versions of portage, write the path in the serialized _eclasses_ when possible. Fix broken is_eclass_data_valid comparison logic. Test for basestring instead of types.DictType so that the test more generic. Reverse the relationship between __contains__ and has_key in all cache classes since python handles the "in" operator more efficiently than a has_key method call. Streamline portage pythonpath handling and add an override analog to how the bash side does it. rename getmaskingreason() to getpmaskcomment() to clarify its function, report each license as a separate mask instead of combining them all together into a single value for getmaskingstatus() need a mutable config instance to use setcpv add function getlicensetexts() to extract license texts relevant to a given cpv (to be used by emerge masked by display) show licenses or pointer to license files on 'masked by' message svn path=/main/branches/prefix/; revision=4831 --- diff --git a/NEWS b/NEWS index a5ecef4ae..a4c96ed62 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ portage-2.1.2 order and detection of circular dependencies. * The world and system sets allow automatic update of all installed slots. * DEPEND atoms support SLOT dependencies of the form ${CATEGORY}/${PN}:${SLOT}. +* Development: Extend PORTAGE_PYM_PATH support to allow overriding the hardcoded + /usr/lib/portage/pym for development/testing purposes portage-2.1.1 ------------ diff --git a/bin/archive-conf b/bin/archive-conf index e50c39078..4909f9b33 100755 --- a/bin/archive-conf +++ b/bin/archive-conf @@ -11,7 +11,7 @@ # import os, sys, string -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage, dispatch_conf diff --git a/bin/chkcontents b/bin/chkcontents index 008b4de4f..65f1a8190 100755 --- a/bin/chkcontents +++ b/bin/chkcontents @@ -9,7 +9,7 @@ # the right files). import string, os.path, os, sys -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage def CONTENTScheck(path): diff --git a/bin/clean_locks b/bin/clean_locks index 855e9fc94..d6cfee151 100755 --- a/bin/clean_locks +++ b/bin/clean_locks @@ -3,8 +3,8 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/bin/clean_locks,v 1.1 2004/09/26 10:44:31 carpaski Exp $ -import os,sys -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +import os,sys,errno +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage_locks, portage_const diff --git a/bin/dispatch-conf b/bin/dispatch-conf index eb18fcfc7..fe524517d 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -15,7 +15,7 @@ from stat import * from random import * import atexit, commands, os, re, shutil, stat, string, sys -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage, dispatch_conf, portage_const diff --git a/bin/ebuild b/bin/ebuild index 5d7f2def8..d47c92582 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -21,7 +21,7 @@ if "merge" in pargs: os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto" os.environ["PORTAGE_CALLER"]="ebuild" -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage, portage_util, portage_const diff --git a/bin/emaint b/bin/emaint index f29013ae2..23ca3bc97 100755 --- a/bin/emaint +++ b/bin/emaint @@ -1,7 +1,7 @@ #!@PYTHON@ -O -import sys -sys.path.insert(0, "@PORTAGE_BASE@/pym") +import sys, os +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) from optparse import OptionParser, OptionValueError import re diff --git a/bin/emerge b/bin/emerge index e0a05f32b..69ef549a4 100755 --- a/bin/emerge +++ b/bin/emerge @@ -21,7 +21,7 @@ except KeyboardInterrupt: sys.exit(1) import os, stat -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) os.environ["PORTAGE_LEGACY_GLOBALS"] = "false" import portage @@ -1359,15 +1359,30 @@ class depgraph: print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") print "!!! One of the following masked packages is required to complete your request:" oldcomment = "" + shown_licenses = [] for p in alleb: mreasons = portage.getmaskingstatus(p, settings=pkgsettings, portdb=portdb) print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")" - comment = portage.getmaskingreason(p, - settings=pkgsettings, portdb=portdb) - if comment and comment != oldcomment: - print comment - oldcomment = comment + if "package.mask" in mreasons: + comment = portage.getpmaskcomment(p, + settings=pkgsettings, portdb=portdb) + if comment and comment != oldcomment: + print comment + oldcomment = comment + licdict = portage.getlicensetexts(p, settings=pkgsettings, portdb=portdb, onlymasked=True) + for lic in licdict.keys(): + if lic+" license" in mreasons and not lic in shown_licenses: + if len(licdict[lic][1]) > 2000: + print "Please read the text of license %s in %s" % (lic, licdict[lic][0]) + print + else: + print "License text for license %s:" % lic + print + print licdict[lic][1] + print + shown_licenses.append(lic) + print print "For more information, see MASKED PACKAGES section in the emerge man page or " print "refer to the Gentoo Handbook." diff --git a/bin/env-update b/bin/env-update index bbb159127..6390ae4d9 100755 --- a/bin/env-update +++ b/bin/env-update @@ -4,7 +4,7 @@ # $Id: /var/cvsroot/gentoo-src/portage/bin/env-update,v 1.9 2004/10/04 13:56:50 vapier Exp $ import os,sys -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) def usage(status): print "Usage: env-update [--no-ldconfig]" diff --git a/bin/fix-db.py b/bin/fix-db.py index 34a422e91..b12b316c8 100755 --- a/bin/fix-db.py +++ b/bin/fix-db.py @@ -4,7 +4,7 @@ # $Id: /var/cvsroot/gentoo-src/portage/bin/fix-db.py,v 1.8 2004/10/11 04:01:00 jstubbs Exp $ import os,sys,re -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) from stat import * from output import * diff --git a/bin/fixpackages b/bin/fixpackages index 8b9172fc2..928a7107c 100755 --- a/bin/fixpackages +++ b/bin/fixpackages @@ -5,7 +5,7 @@ import os,sys os.environ["PORTAGE_CALLER"]="fixpackages" -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage diff --git a/bin/md5check.py b/bin/md5check.py index 16157bd00..df95ad2a8 100755 --- a/bin/md5check.py +++ b/bin/md5check.py @@ -5,7 +5,7 @@ import os,sys,string os.environ["FEATURES"]="mirror cvs" -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage from threading import * diff --git a/bin/pkgname b/bin/pkgname index d60bac803..ef946abe7 100755 --- a/bin/pkgname +++ b/bin/pkgname @@ -3,8 +3,8 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/bin/pkgname,v 1.8 2004/10/04 13:56:50 vapier Exp $ -import sys -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +import sys, os +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage diff --git a/bin/portageq b/bin/portageq index 7bb21d321..f4fe1f5cd 100755 --- a/bin/portageq +++ b/bin/portageq @@ -20,7 +20,7 @@ except KeyboardInterrupt: sys.exit(1) import os -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import types,string diff --git a/bin/regenworld b/bin/regenworld index e8f4f0d5e..ebf315d77 100755 --- a/bin/regenworld +++ b/bin/regenworld @@ -3,9 +3,8 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: /var/cvsroot/gentoo-src/portage/bin/regenworld,v 1.10.2.1 2005/01/11 03:40:57 carpaski Exp $ -import sys -sys.path.insert(0, "@PORTAGE_BASE@/pym") -import os +import sys, os +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import portage, string, re, portage_const __candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ") diff --git a/bin/repoman b/bin/repoman index b4a108da5..3a63c5ce3 100755 --- a/bin/repoman +++ b/bin/repoman @@ -11,7 +11,7 @@ import errno, os, shutil, sys if not hasattr(__builtins__, "set"): from sets import Set as set exename=os.path.basename(sys.argv[0]) -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) version="1.2" allowed_filename_chars="a-zA-Z0-9._-+:" diff --git a/bin/xpak b/bin/xpak index 85553ba27..c983c1439 100755 --- a/bin/xpak +++ b/bin/xpak @@ -3,12 +3,12 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: xpak 3483 2006-06-10 21:40:40Z genone $ -import sys +import sys, os if len(sys.argv)!=3: print "xpak: expecting three arguments." sys.exit(1) -sys.path = ["@PORTAGE_BASE@/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "@PORTAGE_BASE@/pym")) import xpak xpak.xpak(sys.argv[1],sys.argv[2]) diff --git a/pym/cache/anydbm.py b/pym/cache/anydbm.py index ac9081aaf..a632fe12c 100644 --- a/pym/cache/anydbm.py +++ b/pym/cache/anydbm.py @@ -63,7 +63,7 @@ class database(fs_template.FsBased): def iterkeys(self): return iter(self.__db) - def has_key(self, cpv): + def __contains__(self, cpv): return cpv in self.__db def __del__(self): diff --git a/pym/cache/flat_hash.py b/pym/cache/flat_hash.py index 26861e494..bbfb55720 100644 --- a/pym/cache/flat_hash.py +++ b/pym/cache/flat_hash.py @@ -98,7 +98,7 @@ class database(fs_template.FsBased): raise cache_errors.CacheCorruption(cpv, e) - def has_key(self, cpv): + def __contains__(self, cpv): return os.path.exists(os.path.join(self.location, cpv)) diff --git a/pym/cache/flat_list.py b/pym/cache/flat_list.py index 65fe5a781..85efa4c02 100644 --- a/pym/cache/flat_list.py +++ b/pym/cache/flat_list.py @@ -82,7 +82,7 @@ class database(fs_template.FsBased): raise cache_errors.CacheCorruption(cpv, e) - def has_key(self, cpv): + def __contains__(self, cpv): return os.path.exists(os.path.join(self._base, cpv)) diff --git a/pym/cache/metadata.py b/pym/cache/metadata.py index 5c1c593a2..9eace6a27 100644 --- a/pym/cache/metadata.py +++ b/pym/cache/metadata.py @@ -68,8 +68,10 @@ class database(flat_hash.database): if "INHERITED" in d: d["_eclasses_"] = self.ec.get_eclass_data(d["INHERITED"].split(), from_master_only=True) del d["INHERITED"] - else: - d["_eclasses_"] = reconstruct_eclasses(cpv, d["_eclasses_"]) + elif isinstance(d["_eclasses_"], basestring): + # We skip this if flat_hash.database._parse_data() was called above + # because it calls reconstruct_eclasses() internally. + d["_eclasses_"] = reconstruct_eclasses(None, d["_eclasses_"]) return d diff --git a/pym/cache/metadata_overlay.py b/pym/cache/metadata_overlay.py index f4871674e..1716e3dd4 100644 --- a/pym/cache/metadata_overlay.py +++ b/pym/cache/metadata_overlay.py @@ -54,7 +54,7 @@ class database(template.database): else: del self.db_rw[cpv] - def has_key(self, cpv): + def __contains__(self, cpv): try: self[cpv] # validates whiteout when necessary except KeyError: diff --git a/pym/cache/sql_template.py b/pym/cache/sql_template.py index 533b099ec..0734222b1 100644 --- a/pym/cache/sql_template.py +++ b/pym/cache/sql_template.py @@ -196,7 +196,7 @@ class SQLDatabase(template.database): return self.con.fetchone()[0] - def has_key(self, cpv): + def __contains__(self, cpv): if not self.autocommits: try: self.commit() except self._BaseError, e: diff --git a/pym/cache/sqlite.py b/pym/cache/sqlite.py index 571eff39b..6b1a3d323 100644 --- a/pym/cache/sqlite.py +++ b/pym/cache/sqlite.py @@ -200,7 +200,7 @@ class database(fs_template.FsBased): self._db_table["packages"]["package_key"], self._db_escape_string(cpv))) - def has_key(self, cpv): + def __contains__(self, cpv): cursor = self._db_cursor cursor.execute(" ".join( ["SELECT %s FROM %s" % diff --git a/pym/cache/template.py b/pym/cache/template.py index d68138f89..5c72da286 100644 --- a/pym/cache/template.py +++ b/pym/cache/template.py @@ -89,7 +89,7 @@ class database(object): raise NotImplementedError def has_key(self, cpv): - raise NotImplementedError + return cpv in self def keys(self): return tuple(self.iterkeys()) @@ -114,7 +114,7 @@ class database(object): raise NotImplementedError def __contains__(self, cpv): - return self.has_key(cpv) + raise NotImplementedError def get_matches(self, match_dict): """generic function for walking the entire cache db, matching restrictions to @@ -158,10 +158,9 @@ def serialize_eclasses(eclass_dict): return "\t".join(["%s\t%s" % (k, str(v)) \ for k, v in eclass_dict.iteritems()]) """ - """ This is a variation of the old format that uses a relative path instead - of the full path of the eclass. It should only force a regen in older - versions of portage (rather than a traceback).""" - return "\t".join(["%s\teclass\t%s" % (k, str(v)) \ + if not eclass_dict: + return "" + return "\t".join(["%s\t%s\t%s" % (k, v[0], str(v[1])) \ for k, v in eclass_dict.iteritems()]) def reconstruct_eclasses(cpv, eclass_string): @@ -177,11 +176,11 @@ def reconstruct_eclasses(cpv, eclass_string): try: if eclasses[1].isdigit(): for x in xrange(0, len(eclasses), 2): - d[eclasses[x]] = long(eclasses[x + 1]) + d[eclasses[x]] = ("", long(eclasses[x + 1])) else: # The old format contains paths that will be discarded. for x in xrange(0, len(eclasses), 3): - d[eclasses[x]] = long(eclasses[x + 2]) + d[eclasses[x]] = (eclasses[x + 1], long(eclasses[x + 2])) except ValueError: raise cache_errors.CacheCorruption(cpv, "_eclasses_ mtime conversion to long failed") del eclasses diff --git a/pym/dispatch_conf.py b/pym/dispatch_conf.py index 9ca57f0da..e7a7da039 100644 --- a/pym/dispatch_conf.py +++ b/pym/dispatch_conf.py @@ -10,7 +10,7 @@ from stat import * import os, sys, commands, shutil -sys.path = ["/usr/lib/portage/pym"]+sys.path +sys.path.insert(0, os.environ.get("PORTAGE_PYM_PATH", "/usr/lib/portage/pym")) import portage RCS_BRANCH = '1.1.1' diff --git a/pym/eclass_cache.py b/pym/eclass_cache.py index 904e63261..b0f82fd02 100644 --- a/pym/eclass_cache.py +++ b/pym/eclass_cache.py @@ -50,14 +50,19 @@ class cache: except OSError: continue ys=y[:-eclass_len] - self.eclasses[ys] = long(mtime) + self.eclasses[ys] = (x, long(mtime)) self._eclass_locations[ys] = x def is_eclass_data_valid(self, ec_dict): if not isinstance(ec_dict, dict): return False - for eclass, mtime in ec_dict.iteritems(): - if eclass not in self.eclasses or mtime != self.eclasses[eclass]: + for eclass, tup in ec_dict.iteritems(): + cached_data = self.eclasses.get(eclass, None) + """ Only use the mtime for validation since the probability of a + collision is small and, depending on the cache implementation, the + path may not be specified (cache from rsync mirrors, for example). + """ + if cached_data is None or tup[1] != cached_data[1]: return False return True diff --git a/pym/portage.py b/pym/portage.py index c745e7c23..e5d91bccd 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -3837,7 +3837,34 @@ def cpv_expand(mycpv, mydb=None, use_cache=1, settings=None): else: return mykey -def getmaskingreason(mycpv, settings=None, portdb=None): +def getlicensetexts(mycpv, settings=None, portdb=None, onlymasked=True): + if portdb is None: + portdb = globals()["portdb"] + if settings is None: + settings = config(clone=globals()["settings"]) + + license_data = portdb.aux_get(mycpv, ["LICENSE"])[0] + settings.setcpv(mycpv, mydb=portdb) + acceptable_licenses = settings.acceptable_licenses(mycpv) + + def str_matches(myatom): + return (not onlymasked) and (myatom in acceptable_licenses) + + license_list = dep_check(license_data, None, settings, + str_matches=str_matches)[1] + if onlymasked and "*" in acceptable_licenses: + license_list = [] + + rValue = {} + for lic in license_list: + # Account for overlays here? How? + licfilename = os.path.join(settings["PORTDIR"], "licenses", lic) + fd = open(licfilename, "r") + rValue[lic] = (licfilename, fd.read()) + fd.close() + return rValue + +def getpmaskcomment(mycpv, settings=None, portdb=None): from portage_util import grablines if settings is None: settings = globals()["settings"] @@ -3882,10 +3909,12 @@ def getmaskingreason(mycpv, settings=None, portdb=None): return comment i = i + 1 return None +# Compability name +getmaskingreason=getpmaskcomment def getmaskingstatus(mycpv, settings=None, portdb=None): if settings is None: - settings = globals()["settings"] + settings = config(clone=globals()["settings"]) if portdb is None: portdb = globals()["portdb"] mysplit = catpkgsplit(mycpv) @@ -3970,7 +3999,7 @@ def getmaskingstatus(mycpv, settings=None, portdb=None): license_req = dep_check(mylicense, None, settings, str_matches=str_matches)[1] if license_req: - rValue.append(" ".join(license_req) + " license(s)") + rValue += [x+" license" for x in license_req] return rValue @@ -4459,6 +4488,8 @@ class vardbapi(dbapi): return [] returnme=[] for x in list: + if x.startswith("."): + continue if x[0] == '-': #writemsg(red("INCOMPLETE MERGE:")+str(x[len("-MERGING-"):])+"\n") continue