summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-04-11 22:15:44 +0000
committerZac Medico <zmedico@gentoo.org>2006-04-11 22:15:44 +0000
commitb446968ebfcafd5a6c1a085aa89b37a502c8020b (patch)
tree6ff65e3b188c54637b53aaf0e9a4d643fa610079 /sys-apps
parentStable on sparc wrt #122727 (diff)
downloadgentoo-2-b446968ebfcafd5a6c1a085aa89b37a502c8020b.tar.gz
gentoo-2-b446968ebfcafd5a6c1a085aa89b37a502c8020b.tar.bz2
gentoo-2-b446968ebfcafd5a6c1a085aa89b37a502c8020b.zip
2.1_pre8-r1 revbump
(Portage version: 2.1_pre8-r1)
Diffstat (limited to 'sys-apps')
-rw-r--r--sys-apps/portage/ChangeLog15
-rw-r--r--sys-apps/portage/files/2.1/pre8/1000_r3120_fetchlist_dict.patch45
-rw-r--r--sys-apps/portage/files/2.1/pre8/1010_r3123_manifest2_fixes.patch502
-rw-r--r--sys-apps/portage/files/2.1/pre8/1020_r3118_bug_121368.patch102
-rw-r--r--sys-apps/portage/files/2.1/pre8/1030_r3128_bug_129559_qmerge.patch14
-rw-r--r--sys-apps/portage/files/2.1/pre8/1040_r3126_bug_129244_ebuild_phase.patch44
-rw-r--r--sys-apps/portage/files/2.1/pre8/1050_r3131_lazy_databases.patch44
-rw-r--r--sys-apps/portage/files/digest-portage-2.1_pre8-r13
-rw-r--r--sys-apps/portage/portage-2.1_pre8-r1.ebuild191
9 files changed, 959 insertions, 1 deletions
diff --git a/sys-apps/portage/ChangeLog b/sys-apps/portage/ChangeLog
index 29ac347506e9..f533d2f74a50 100644
--- a/sys-apps/portage/ChangeLog
+++ b/sys-apps/portage/ChangeLog
@@ -1,6 +1,19 @@
# ChangeLog for sys-apps/portage
# Copyright 1999-2006 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/portage/ChangeLog,v 1.107 2006/04/09 06:56:52 zmedico Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/portage/ChangeLog,v 1.108 2006/04/11 22:15:44 zmedico Exp $
+
+*portage-2.1_pre8-r1 (11 Apr 2006)
+
+ 11 Apr 2006; <zmedico@gentoo.org> +portage-2.1_pre8-r1.ebuild,
+ +files/2.1/pre8/1000_r3120_fetchlist_dict.patch,
+ +files/2.1/pre8/1010_r3123_manifest2_fixes.patch,
+ +files/2.1/pre8/1020_r3118_bug_121368.patch,
+ +files/2.1/pre8/1030_r3128_bug_129559_qmerge.patch,
+ +files/2.1/pre8/1040_r3126_bug_129244_ebuild_phase.patch,
+ +files/2.1/pre8/1050_r3131_lazy_databases.patch:
+ 2.1_pre8-r1 bug fix revbump. This is in package.mask because the new
+ Manifest2 support (see GLEP 44) needs testing. Gentoo devs, please limit the
+ number of repoman commits with Manifest2 while we test this.
*portage-2.1_pre7-r5 (09 Apr 2006)
diff --git a/sys-apps/portage/files/2.1/pre8/1000_r3120_fetchlist_dict.patch b/sys-apps/portage/files/2.1/pre8/1000_r3120_fetchlist_dict.patch
new file mode 100644
index 000000000000..1d8961d23d98
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1000_r3120_fetchlist_dict.patch
@@ -0,0 +1,45 @@
+=== modified file 'pym/portage.py'
+--- pym/portage.py
++++ pym/portage.py
+@@ -6379,6 +6344,41 @@
+ "Is this a regular package (does it have a CATEGORY file? A dblink can be virtual *and* regular)"
+ return os.path.exists(self.dbdir+"/CATEGORY")
+
++class FetchlistDict(UserDict.DictMixin):
++ """This provide a mapping interface to retrieve fetch lists. It's used
++ to allow portage_manifest.Manifest to access fetch lists via a standard
++ mapping interface rather than use the dbapi directly."""
++ def __init__(self, pkgdir, settings):
++ """pkgdir is a directory containing ebuilds and settings is passed into
++ portdbapi.getfetchlist for __getitem__ calls."""
++ self.pkgdir = pkgdir
++ self.cp = os.sep.join(pkgdir.split(os.sep)[-2:])
++ self.settings = settings
++ self.porttrees = [os.path.dirname(os.path.dirname(pkgdir))]
++ def __getitem__(self, pkg_key):
++ """Returns the complete fetch list for a given package."""
++ global portdb # has the global auxdb caches
++ all_trees = portdb.porttrees
++ # This ensures that the fetchlist comes from the correct portage tree.
++ portdb.porttrees = self.porttrees
++ fetchlist = portdb.getfetchlist(pkg_key, mysettings=self.settings, all=True)[1]
++ # XXX The db is global so we restore it's trees back to their original state.
++ portdb.porttrees = all_trees
++ return fetchlist
++ def has_key(self, pkg_key):
++ """Returns true if the given package exists within pkgdir."""
++ return pkg_key in self.keys()
++ def keys(self):
++ """Returns keys for all packages within pkgdir"""
++ global portdb # has the global auxdb caches
++ all_trees = portdb.porttrees
++ # This ensures that the key list comes from the correct portage tree.
++ portdb.porttrees = self.porttrees
++ mykeys = portdb.cp_list(self.cp)
++ # XXX The db is global so we restore it's trees back to their original state.
++ portdb.porttrees = all_trees
++ return mykeys
++
+ def cleanup_pkgmerge(mypkg,origdir):
+ shutil.rmtree(settings["PORTAGE_TMPDIR"]+"/binpkgs/"+mypkg)
+ if os.path.exists(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment"):
diff --git a/sys-apps/portage/files/2.1/pre8/1010_r3123_manifest2_fixes.patch b/sys-apps/portage/files/2.1/pre8/1010_r3123_manifest2_fixes.patch
new file mode 100644
index 000000000000..af768d94329d
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1010_r3123_manifest2_fixes.patch
@@ -0,0 +1,502 @@
+=== modified file 'bin/repoman'
+--- bin/repoman
++++ bin/repoman
+@@ -795,7 +795,9 @@
+ fails["CVS/Entries.IO_error"].append(checkdir+"/files/CVS/Entries")
+ continue
+
+- mf=Manifest(checkdir, db=portage.db["/"]["porttree"].dbapi, mysettings=repoman_settings)
++ mf = Manifest(checkdir,
++ portage.FetchlistDict(checkdir, repoman_settings),
++ repoman_settings["DISTDIR"])
+ mydigests=mf.getTypeDigests("DIST")
+ myfiles_all = []
+
+@@ -878,6 +880,8 @@
+ if y == "CVS":
+ continue
+ for z in os.listdir(checkdir+"/files/"+y):
++ if z == "CVS":
++ continue
+ filesdirlist.append(y+"/"+z)
+ # current policy is no files over 20k, this is the check.
+ elif mystat.st_size > 20480:
+@@ -1613,8 +1617,8 @@
+ if "sign" in portage.features:
+ mydone=[]
+ if repolevel==3: # In a package dir
+- repoman_settings["O"]="./"
+- while(gpgsign(repoman_settings["O"]+"/Manifest")):
++ repoman_settings["O"] = "."
++ while(gpgsign(os.path.join(repoman_settings["O"], "Manifest"))):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+@@ -1626,8 +1630,8 @@
+ if xs[0] in mydone:
+ continue
+ mydone.append(xs[0])
+- repoman_settings["O"]="./"+xs[0]
+- while(gpgsign(repoman_settings["O"]+"/Manifest")):
++ repoman_settings["O"] = os.path.join(".", xs[0])
++ while(gpgsign(os.path.join(repoman_settings["O"], "Manifest"))):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+@@ -1640,8 +1644,8 @@
+ if string.join(xs[:2],"/") in mydone:
+ continue
+ mydone.append(string.join(xs[:2],"/"))
+- repoman_settings["O"]="./"+string.join(xs[:2],"/")
+- while(gpgsign(repoman_settings["O"]+"/Manifest")):
++ repoman_settings["O"] = os.path.join(".", xs[0], xs[1])
++ while(gpgsign(os.path.join(repoman_settings["O"], "Manifest"))):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+
+=== modified file 'pym/portage.py'
+--- pym/portage.py
++++ pym/portage.py
+@@ -30,6 +30,7 @@
+ import commands
+ from time import sleep
+ from random import shuffle
++ import UserDict
+ except ImportError, e:
+ sys.stderr.write("\n\n")
+ sys.stderr.write("!!! Failed to complete python imports. These are internal modules for\n")
+@@ -2058,7 +2059,7 @@
+ return 0
+ return 1
+
+-def digestgen(myarchives,mysettings,db=None,overwrite=1,manifestonly=0):
++def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0):
+ """generates digest file if missing. Assumes all files are available. If
+ overwrite=0, the digest will only be created if it doesn't already exist.
+ DEPRECATED: this now only is a compability wrapper for
+@@ -2069,26 +2070,16 @@
+ # (e.g. cvs stuff should be in ebuild(1) and/or repoman)
+ # TODO: error/exception handling
+
+- if db is None:
+- db = portagetree().dbapi
+-
+- mf = Manifest(mysettings["O"], db, mysettings)
++ global settings
++ mf = Manifest(mysettings["O"], FetchlistDict(mysettings["O"], mysettings), mysettings["DISTDIR"])
++ mf.create(assumeDistfileHashes=True)
+ for f in myarchives:
+ # the whole type evaluation is only for the case that myarchives isn't a
+ # DIST file as create() determines the type on its own
+- mytype = mf.guessType(f)
+- if mytype == "AUX":
+- f = f[5:]
+- elif mytype is None:
+- continue
+- myrealtype = mf.findFile(f)
+- if myrealtype != None:
+- mytype = myrealtype
+ writemsg(">>> Creating Manifest for %s\n" % mysettings["O"])
+- mf.create(assumeDistfileHashes=True)
+ try:
+ writemsg(">>> Adding digests for file %s\n" % f)
+- mf.updateFileHashes(mytype, f, checkExisting=False, reuseExisting=not os.path.exists(os.path.join(mysettings["DISTDIR"], f)))
++ mf.updateHashesGuessType(f, checkExisting=False, reuseExisting=not os.path.exists(os.path.join(mysettings["DISTDIR"], f)))
+ except portage_exception.FileNotFound, e:
+ writemsg("!!! File %s doesn't exist, can't update Manifest\n" % str(e))
+ return 0
+@@ -2098,7 +2089,7 @@
+
+ return 1
+
+-def digestParseFile(myfilename,mysettings=None,db=None):
++def digestParseFile(myfilename, mysettings=None):
+ """(filename) -- Parses a given file for entries matching:
+ <checksumkey> <checksum_hex_string> <filename> <filesize>
+ Ignores lines that don't start with a valid checksum identifier
+@@ -2109,48 +2100,17 @@
+
+ mysplit = myfilename.split(os.sep)
+ if mysplit[-2] == "files" and mysplit[-1].startswith("digest-"):
+- pkgdir = os.sep+os.sep.join(mysplit[:-2])
++ pkgdir = os.sep + os.sep.join(mysplit[:-2]).strip(os.sep)
+ elif mysplit[-1] == "Manifest":
+- pkgdir = os.sep+os.sep.join(mysplit[:-1])
+-
+- if db is None:
+- db = portagetree().dbapi
++ pkgdir = os.sep + os.sep.join(mysplit[:-1]).strip(os.sep)
++
+ if mysettings is None:
++ global settings
+ mysettings = config(clone=settings)
+
+- mf = Manifest(pkgdir, db, mysettings)
++ mf = Manifest(pkgdir, FetchlistDict(pkgdir, mysettings), mysettings["DISTDIR"])
+
+ return mf.getDigests()
+-
+- #########################################
+- # Old code that's replaced by the above #
+- #########################################
+-
+- if not os.path.exists(myfilename):
+- return None
+- mylines = portage_util.grabfile(myfilename, compat_level=1)
+-
+- mydigests={}
+- for x in mylines:
+- myline=string.split(x)
+- if len(myline) < 4:
+- #invalid line
+- continue
+- if myline[0] not in portage_checksum.get_valid_checksum_keys():
+- continue
+- mykey = myline.pop(0)
+- myhash = myline.pop(0)
+- mysize = long(myline.pop())
+- myfn = string.join(myline, " ")
+- if myfn not in mydigests:
+- mydigests[myfn] = {}
+- mydigests[myfn][mykey] = myhash
+- if "size" in mydigests[myfn]:
+- if mydigests[myfn]["size"] != mysize:
+- raise portage_exception.DigestException, "Conflicting sizes in digest: %(filename)s" % {"filename":myfilename}
+- else:
+- mydigests[myfn]["size"] = mysize
+- return mydigests
+
+ # XXXX strict was added here to fix a missing name error.
+ # XXXX It's used below, but we're not paying attention to how we get it?
+@@ -2194,15 +2154,13 @@
+ return 1
+
+
+-def digestcheck(myfiles, mysettings, strict=0, justmanifest=0, db=None):
++def digestcheck(myfiles, mysettings, strict=0, justmanifest=0):
+ """Verifies checksums. Assumes all files have been downloaded.
+ DEPRECATED: this is now only a compability wrapper for
+ portage_manifest.Manifest()."""
+
+ pkgdir = mysettings["O"]
+- if db is None:
+- db = portagetree().dbapi
+- mf = Manifest(pkgdir, db, mysettings)
++ mf = Manifest(pkgdir, FetchlistDict(pkgdir, mysettings), mysettings["DISTDIR"])
+ try:
+ if strict:
+ print ">>> checking ebuild checksums",
+@@ -2750,6 +2708,28 @@
+ if need_distfiles and not fetch(fetchme, mysettings, listonly=listonly, fetchonly=fetchonly):
+ return 1
+
++ if mydo=="fetch" and listonly:
++ return 0
++
++ if "digest" in features:
++ #generate digest if it doesn't exist.
++ if mydo=="digest":
++ return (not digestgen(aalist,mysettings,overwrite=1))
++ else:
++ digestgen(aalist,mysettings,overwrite=0)
++ elif mydo=="digest":
++ #since we are calling "digest" directly, recreate the digest even if it already exists
++ return (not digestgen(aalist,mysettings,overwrite=1))
++ if mydo=="manifest":
++ return (not digestgen(aalist,mysettings,overwrite=1,manifestonly=1))
++
++ # See above comment about fetching only when needed
++ if not digestcheck(checkme, mysettings, ("strict" in features), (mydo not in ["digest","fetch","unpack"] and settings["PORTAGE_CALLER"] == "ebuild" and "noauto" in features)):
++ return 1
++
++ if mydo=="fetch":
++ return 0
++
+ # inefficient. improve this logic via making actionmap easily searchable to see if we're in the chain of what
+ # will be executed, either that or forced N doebuild calls instead of a single set of phase calls.
+ if (mydo not in ("setup", "clean", "postinst", "preinst", "prerm", "fetch", "digest", "manifest") and
+@@ -2774,28 +2754,6 @@
+ except OSError:
+ print "!!! Failed symlinking in '%s' to ebuild distdir" % file
+ raise
+-
+- if mydo=="fetch" and listonly:
+- return 0
+-
+- if "digest" in features:
+- #generate digest if it doesn't exist.
+- if mydo=="digest":
+- return (not digestgen(aalist,mysettings,overwrite=1))
+- else:
+- digestgen(aalist,mysettings,overwrite=0)
+- elif mydo=="digest":
+- #since we are calling "digest" directly, recreate the digest even if it already exists
+- return (not digestgen(aalist,mysettings,overwrite=1))
+- if mydo=="manifest":
+- return (not digestgen(aalist,mysettings,overwrite=1,manifestonly=1))
+-
+- # See above comment about fetching only when needed
+- if not digestcheck(checkme, mysettings, ("strict" in features), (mydo not in ["digest","fetch","unpack"] and settings["PORTAGE_CALLER"] == "ebuild" and "noauto" in features)):
+- return 1
+-
+- if mydo=="fetch":
+- return 0
+
+ #initial dep checks complete; time to process main commands
+
+=== modified file 'pym/portage_checksum.py'
+--- pym/portage_checksum.py
++++ pym/portage_checksum.py
+@@ -94,7 +94,9 @@
+ if mydict["size"] != mysize:
+ return False,("Filesize does not match recorded size", mysize, mydict["size"])
+ except OSError, e:
+- return False, str(e)
++ if e.errno == errno.ENOENT:
++ raise portage_exception.FileNotFound(filename)
++ return False, (str(e), None, None)
+ for x in mydict.keys():
+ if x == "size":
+ continue
+
+=== modified file 'pym/portage_manifest.py'
+--- pym/portage_manifest.py
++++ pym/portage_manifest.py
+@@ -3,8 +3,9 @@
+ # $Header: $
+
+ import errno, os, sets
+-
+-import portage, portage_exception, portage_versions, portage_const
++from itertools import imap
++
++import portage_exception, portage_versions, portage_const
+ from portage_checksum import *
+ from portage_exception import *
+ from portage_util import write_atomic
+@@ -25,11 +26,11 @@
+ return not (filename in ["CVS", ".svn", "files", "Manifest"] or filename.endswith(".ebuild"))
+
+ class Manifest(object):
+- def __init__(self, pkgdir, db, mysettings, manifest1_compat=True, from_scratch=False):
+- """ create new Manifest instance for package in pkgdir, using db and mysettings for metadata lookups,
++ def __init__(self, pkgdir, fetchlist_dict, distdir, manifest1_compat=True, from_scratch=False):
++ """ create new Manifest instance for package in pkgdir
+ and add compability entries for old portage versions if manifest1_compat == True.
+ Do not parse Manifest file if from_scratch == True (only for internal use) """
+- self.pkgdir = pkgdir+os.sep
++ self.pkgdir = pkgdir.rstrip(os.sep) + os.sep
+ self.fhashdict = {}
+ self.hashes = portage_const.MANIFEST2_HASH_FUNCTIONS[:]
+ self.hashes.append("size")
+@@ -41,12 +42,8 @@
+ if not from_scratch:
+ self._read()
+ self.compat = manifest1_compat
+- self.db = db
+- self.mysettings = mysettings
+- if mysettings.has_key("PORTAGE_ACTUAL_DISTDIR"):
+- self.distdir = mysettings["PORTAGE_ACTUAL_DISTDIR"]
+- else:
+- self.distdir = mysettings["DISTDIR"]
++ self.fetchlist_dict = fetchlist_dict
++ self.distdir = distdir
+
+ def guessType(self, filename):
+ """ Perform a best effort guess of which type the given filename is, avoid using this if possible """
+@@ -79,9 +76,11 @@
+ def _readDigests(self):
+ """ Parse old style digest files for this Manifest instance """
+ mycontent = ""
+- for d in portage.listdir(os.path.join(self.pkgdir, "files"), filesonly=True, recursive=False):
++ for d in os.listdir(os.path.join(self.pkgdir, "files")):
+ if d.startswith("digest-"):
+- mycontent += open(os.path.join(self.pkgdir, "files", d), "r").read()
++ f = open(os.path.join(self.pkgdir, "files", d), "r")
++ mycontent += f.read()
++ f.close()
+ return mycontent
+
+ def _read(self):
+@@ -124,7 +123,7 @@
+
+ def _writeDigests(self, force=False):
+ """ Create old style digest files for this Manifest instance """
+- cpvlist = [os.path.join(self.pkgdir.rstrip(os.sep).split(os.sep)[-2], x[:-7]) for x in portage.listdir(self.pkgdir) if x.endswith(".ebuild")]
++ cpvlist = [os.path.join(self._pkgdir_category(), x[:-7]) for x in os.listdir(self.pkgdir) if x.endswith(".ebuild")]
+ rval = []
+ try:
+ os.makedirs(os.path.join(self.pkgdir, "files"))
+@@ -134,7 +133,7 @@
+ else:
+ raise
+ for cpv in cpvlist:
+- dname = os.path.join(self.pkgdir, "files", "digest-"+portage.catsplit(cpv)[1])
++ dname = os.path.join(self.pkgdir, "files", "digest-%s" % self._catsplit(cpv)[1])
+ distlist = self._getCpvDistfiles(cpv)
+ update_digest = True
+ if not force:
+@@ -194,7 +193,7 @@
+ mylines = []
+ for dname in digests:
+ myhashes = perform_multiple_checksums(dname, portage_const.MANIFEST1_HASH_FUNCTIONS+["size"])
+- for h in myhashes.keys():
++ for h in myhashes:
+ mylines.append((" ".join([h, str(myhashes[h]), os.path.join("files", os.path.basename(dname)), str(myhashes["size"])])))
+ fd.write("\n".join(mylines))
+ fd.write("\n")
+@@ -258,7 +257,7 @@
+ self.fhashdict[ftype][fname] = {}
+ if hashdict != None:
+ self.fhashdict[ftype][fname].update(hashdict)
+- if not portage_const.MANIFEST2_REQUIRED_HASH in self.fhashdict[ftype][fname].keys():
++ if not portage_const.MANIFEST2_REQUIRED_HASH in self.fhashdict[ftype][fname]:
+ self.updateFileHashes(ftype, fname)
+
+ def removeFile(self, ftype, fname):
+@@ -267,7 +266,7 @@
+
+ def hasFile(self, ftype, fname):
+ """ Return wether the Manifest contains an entry for the given type,filename pair """
+- return (fname in self.fhashdict[ftype].keys())
++ return (fname in self.fhashdict[ftype])
+
+ def findFile(self, fname):
+ """ Return entrytype of the given file if present in Manifest or None if not present """
+@@ -286,8 +285,10 @@
+ distfilehashes = self.fhashdict["DIST"]
+ else:
+ distfilehashes = {}
+- self.__init__(self.pkgdir, self.db, self.mysettings, from_scratch=True)
+- for f in portage.listdir(self.pkgdir, filesonly=True, recursive=False):
++ self.__init__(self.pkgdir, self.fetchlist_dict, self.distdir, from_scratch=True)
++ for pkgdir, pkgdir_dirs, pkgdir_files in os.walk(self.pkgdir):
++ break
++ for f in pkgdir_files:
+ if f.endswith(".ebuild"):
+ mytype = "EBUILD"
+ elif manifest2MiscfileFilter(f):
+@@ -295,11 +296,18 @@
+ else:
+ continue
+ self.fhashdict[mytype][f] = perform_multiple_checksums(self.pkgdir+f, self.hashes)
+- for f in portage.listdir(self.pkgdir+"files", filesonly=True, recursive=True):
++ recursive_files = []
++ cut_len = len(os.path.join(self.pkgdir, "files") + os.sep)
++ for parentdir, dirs, files in os.walk(os.path.join(self.pkgdir, "files")):
++ for f in files:
++ full_path = os.path.join(parentdir, f)
++ recursive_files.append(full_path[cut_len:])
++ for f in recursive_files:
+ if not manifest2AuxfileFilter(f):
+ continue
+- self.fhashdict["AUX"][f] = perform_multiple_checksums(self.pkgdir+"files"+os.sep+f, self.hashes)
+- cpvlist = [os.path.join(self.pkgdir.rstrip(os.sep).split(os.sep)[-2], x[:-7]) for x in portage.listdir(self.pkgdir) if x.endswith(".ebuild")]
++ self.fhashdict["AUX"][f] = perform_multiple_checksums(
++ os.path.join(self.pkgdir, "files", f.lstrip(os.sep)), self.hashes)
++ cpvlist = [os.path.join(self._pkgdir_category(), x[:-7]) for x in os.listdir(self.pkgdir) if x.endswith(".ebuild")]
+ distlist = []
+ for cpv in cpvlist:
+ distlist.extend(self._getCpvDistfiles(cpv))
+@@ -307,11 +315,14 @@
+ fname = os.path.join(self.distdir, f)
+ if os.path.exists(fname):
+ self.fhashdict["DIST"][f] = perform_multiple_checksums(fname, self.hashes)
+- elif assumeDistfileHashes and f in distfilehashes.keys():
++ elif assumeDistfileHashes and f in distfilehashes:
+ self.fhashdict["DIST"][f] = distfilehashes[f]
+ else:
+ raise FileNotFound(fname)
+-
++
++ def _pkgdir_category(self):
++ return self.pkgdir.rstrip(os.sep).split(os.sep)[-2]
++
+ def _getAbsname(self, ftype, fname):
+ if ftype == "DIST":
+ absname = os.path.join(self.distdir, fname)
+@@ -326,7 +337,7 @@
+ self.checkTypeHashes(t, ignoreMissingFiles=ignoreMissingFiles)
+
+ def checkTypeHashes(self, idtype, ignoreMissingFiles=False):
+- for f in self.fhashdict[idtype].keys():
++ for f in self.fhashdict[idtype]:
+ self.checkFileHashes(idtype, f, ignoreMissing=ignoreMissingFiles)
+
+ def checkFileHashes(self, ftype, fname, ignoreMissing=False):
+@@ -343,7 +354,7 @@
+ self.checkTypeHashes("AUX", ignoreMissingFiles=False)
+ if checkMiscfiles:
+ self.checkTypeHashes("MISC", ignoreMissingFiles=False)
+- ebuildname = portage.catsplit(cpv)[1]+".ebuild"
++ ebuildname = "%s.ebuild" % self._catsplit(cpv)[1]
+ self.checkFileHashes("EBUILD", ebuildname, ignoreMissing=False)
+ if checkDistfiles:
+ if onlyDistfiles:
+@@ -352,26 +363,26 @@
+
+ def _getCpvDistfiles(self, cpv):
+ """ Get a list of all DIST files associated to the given cpv """
+- return self.db.getfetchlist(cpv, mysettings=self.mysettings, all=True)[1]
++ return self.fetchlist_dict[cpv]
+
+ def updateFileHashes(self, ftype, fname, checkExisting=True, ignoreMissing=True, reuseExisting=False):
+ """ Regenerate hashes for the given file """
+ if checkExisting:
+- self.checkFileHashes(fname)
++ self.checkFileHashes(ftype, fname, ignoreMissing=ignoreMissing)
+ if not ignoreMissing and not self.fhashdict[ftype].has_key(fname):
+ raise FileNotInManifestException(fname)
+ if not self.fhashdict[ftype].has_key(fname):
+ self.fhashdict[ftype][fname] = {}
+ myhashkeys = list(self.hashes)
+ if reuseExisting:
+- for k in [h for h in self.fhashdict[ftype][fname].keys() if h in myhashkeys]:
++ for k in [h for h in self.fhashdict[ftype][fname] if h in myhashkeys]:
+ myhashkeys.remove(k)
+ myhashes = perform_multiple_checksums(self._getAbsname(ftype, fname), myhashkeys)
+ self.fhashdict[ftype][fname].update(myhashes)
+
+ def updateTypeHashes(self, idtype, checkExisting=False, ignoreMissingFiles=True):
+ """ Regenerate all hashes for all files of the given type """
+- for fname in self.fhashdict[idtype].keys():
++ for fname in self.fhashdict[idtype]:
+ self.updateFileHashes(idtype, fname, checkExisting)
+
+ def updateAllHashes(self, checkExisting=False, ignoreMissingFiles=True):
+@@ -384,10 +395,23 @@
+ files)."""
+ self.updateTypeHashes("AUX", ignoreMissingFiles=ignoreMissingFiles)
+ self.updateTypeHashes("MISC", ignoreMissingFiles=ignoreMissingFiles)
+- ebuildname = portage.catsplit(cpv)[1]+".ebuild"
++ ebuildname = "%s.ebuild" % self._catsplit(cpv)[1]
+ self.updateFileHashes("EBUILD", ebuildname, ignoreMissingFiles=ignoreMissingFiles)
+ for f in self._getCpvDistfiles(cpv):
+ self.updateFileHashes("DIST", f, ignoreMissingFiles=ignoreMissingFiles)
++
++ def updateHashesGuessType(self, fname, *args, **kwargs):
++ """ Regenerate hashes for the given file (guesses the type and then
++ calls updateFileHashes)."""
++ mytype = self.guessType(fname)
++ if mytype == "AUX":
++ fname = fname[len("files" + os.sep):]
++ elif mytype is None:
++ return
++ myrealtype = self.findFile(fname)
++ if myrealtype is not None:
++ mytype = myrealtype
++ return self.updateFileHashes(mytype, fname, *args, **kwargs)
+
+ def getFileData(self, ftype, fname, key):
+ """ Return the value of a specific (type,filename,key) triple, mainly useful
+@@ -410,3 +434,8 @@
+ elif len(mysplit) > 4 and mysplit[0] in portage_const.MANIFEST2_IDENTIFIERS and ((len(mysplit) - 3) % 2) == 0 and not 2 in rVal:
+ rVal.append(2)
+ return rVal
++
++ def _catsplit(self, pkg_key):
++ """Split a category and package, returning a list of [cat, pkg].
++ This is compatible with portage.catsplit()"""
++ return pkg_key.split("/", 1)
+
diff --git a/sys-apps/portage/files/2.1/pre8/1020_r3118_bug_121368.patch b/sys-apps/portage/files/2.1/pre8/1020_r3118_bug_121368.patch
new file mode 100644
index 000000000000..efdac4703c33
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1020_r3118_bug_121368.patch
@@ -0,0 +1,102 @@
+=== modified file 'bin/misc-functions.sh'
+--- bin/misc-functions.sh
++++ bin/misc-functions.sh
+@@ -184,77 +184,27 @@
+ unset INSTALLTOD
+ fi
+
+- # dumps perms to stdout. if error, no perms dumped.
+- function stat_perms() {
+- local f
+- # only define do_stat if it hasn't been already
+- if ! type -p do_stat &> /dev/null; then
+- if ! type -p stat &>/dev/null; then
+- do_stat() {
+- # Generic version -- Octal result
+- python -c "import os,stat; print '%o' % os.stat('$1')[stat.ST_MODE]"
+- }
+- else
+- if [ "${USERLAND}" == "BSD" ] || [ "${USERLAND}" == "Darwin" ]; then
+- do_stat() {
+- # BSD version -- Octal result
+- $(type -p stat) -f '%p' "$1"
+- }
+- else
+- do_stat() {
+- # Linux version -- Hex result converted to Octal
+- f=$($(type -p stat) -c '%f' "$1") || return $?
+- printf '%o' "0x$f"
+- }
+- fi
+- fi
+- fi
+-
+- f=$(do_stat "$@") || return
+- f="${f:2:4}"
+- echo $f
+- }
+-
+- local file s
+- local count=0
+- find "${D}/" -user portage | while read file; do
+- count=$(( $count + 1 ))
+- if [ -L "${file}" ]; then
+- lchown ${PORTAGE_INST_UID:-0} "${file}"
+- else
+- s=$(stat_perms "$file")
+- if [ -z "${s}" ]; then
+- ewarn "failed stat_perm'ing $file. User intervention during install isn't wise..."
+- continue
+- fi
+- chown ${PORTAGE_INST_UID:-0} "$file"
+- chmod "$s" "$file"
+- fi
+- done
+- if (( $count > 0 )); then
+- ewarn "$count files were installed with user portage!"
+- fi
+-
+- count=0
+- find "${D}/" -group portage | while read file; do
+- count=$(( $count + 1 ))
+- if [ -L "${file}" ]; then
+- lchgrp ${PORTAGE_INST_GID:-0} "${file}"
+- else
+- s=$(stat_perms "$file")
+- if [ -z "${s}" ]; then
+- echo "failed stat_perm'ing '$file' . User intervention during install isn't wise..."
+- continue
+- fi
+- chgrp ${PORTAGE_INST_GID:-0} "$file"
+- chmod "$s" "$file"
+- fi
+- done
+- if (( $count > 0 )); then
+- ewarn "$count files were installed with group portage!"
+- fi
+-
+- unset -f stat_perms
++ local file="${T}/find-portage-log"
++ local count=$(find "${D}"/ -user portage | wc -l)
++ if [[ ${count} -gt 0 ]] ; then
++ ewarn "${count} files were installed with user portage!"
++ find "${D}"/ -xtype l -user portage -print0 > "${file}"
++ [[ -s ${file} ]] && cat "${file}" | xargs -0 chown -h ${PORTAGE_INST_UID:-0}
++ find "${D}"/ -user portage -print0 > "${file}"
++ [[ -s ${file} ]] && cat "${file}" | xargs -0 chown ${PORTAGE_INST_UID:-0}
++ rm -f "${file}"
++ fi
++
++ count=$(find "${D}"/ -group portage | wc -l)
++ if [[ ${count} -gt 0 ]] ; then
++ ewarn "${count} files were installed with group portage!"
++
++ find "${D}"/ -xtype l -group portage -print0 > "${file}"
++ [[ -s ${file} ]] && cat "${file}" | xargs -0 chgrp -h ${PORTAGE_INST_GID:-0}
++ find "${D}"/ -group portage -print0 > "${file}"
++ [[ -s ${file} ]] && cat "${file}" | xargs -0 chgrp ${PORTAGE_INST_GID:-0}
++ rm -f "${file}"
++ fi
+
+ # Portage regenerates this on the installed system.
+ if [ -f "${D}/usr/share/info/dir.gz" ]; then
diff --git a/sys-apps/portage/files/2.1/pre8/1030_r3128_bug_129559_qmerge.patch b/sys-apps/portage/files/2.1/pre8/1030_r3128_bug_129559_qmerge.patch
new file mode 100644
index 000000000000..8ed07a48e2ff
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1030_r3128_bug_129559_qmerge.patch
@@ -0,0 +1,14 @@
+=== modified file 'pym/portage.py'
+--- pym/portage.py
++++ pym/portage.py
+@@ -2715,6 +2715,9 @@
+ if not os.path.exists(mysettings["PORTAGE_BUILDDIR"]+"/.installed"):
+ print "!!! mydo=qmerge, but install phase hasn't been ran"
+ sys.exit(1)
++ # qmerge is a special phase that implies noclean.
++ if "noclean" not in mysettings.features:
++ mysettings.features.append("noclean")
+ #qmerge is specifically not supposed to do a runtime dep check
+ return merge(mysettings["CATEGORY"],mysettings["PF"],mysettings["D"],mysettings["PORTAGE_BUILDDIR"]+"/build-info",myroot,mysettings,myebuild=mysettings["EBUILD"],mytree=tree)
+ elif mydo=="merge":
+
diff --git a/sys-apps/portage/files/2.1/pre8/1040_r3126_bug_129244_ebuild_phase.patch b/sys-apps/portage/files/2.1/pre8/1040_r3126_bug_129244_ebuild_phase.patch
new file mode 100644
index 000000000000..6fa539fdf458
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1040_r3126_bug_129244_ebuild_phase.patch
@@ -0,0 +1,44 @@
+=== modified file 'bin/ebuild.sh'
+--- bin/ebuild.sh
++++ bin/ebuild.sh
+@@ -11,6 +11,8 @@
+ SANDBOX_PREDICT="${SANDBOX_PREDICT}:${PORTAGE_GPG_DIR}"
+ fi
+
++declare -rx EBUILD_PHASE
++
+ if [ "$*" != "depend" ] && [ "$*" != "clean" ] && [ "$*" != "nofetch" ]; then
+ if [ -f "${T}/environment" ]; then
+ source "${T}/environment" &>/dev/null
+@@ -20,8 +22,6 @@
+ if [ -n "$#" ]; then
+ ARGS="${*}"
+ fi
+-
+-declare -rx EBUILD_PHASE="$*"
+
+ # Prevent aliases from causing portage to act inappropriately.
+ # Make sure it's before everything so we don't mess aliases that follow.
+
+=== modified file 'pym/portage.py'
+--- pym/portage.py
++++ pym/portage.py
+@@ -2197,7 +2197,9 @@
+ if retval:
+ return retval
+ kwargs = actionmap[mydo]["args"]
++ mysettings["EBUILD_PHASE"] = mydo
+ phase_retval = spawn(actionmap[mydo]["cmd"] % mydo, mysettings, debug=debug, logfile=logfile, **kwargs)
++ del mysettings["EBUILD_PHASE"]
+ if phase_retval == os.EX_OK:
+ if mydo == "install":
+ mycommand = " ".join([MISC_SH_BINARY, "install_qa_check"])
+@@ -2246,6 +2246,8 @@
+ # XXX: that creates a deadlock... Really need to isolate that.
+ mysettings.reset(use_cache=use_cache)
+ mysettings.setcpv(mycpv,use_cache=use_cache)
++
++ mysettings["EBUILD_PHASE"] = mydo
+
+ if debug: # Otherwise it overrides emerge's settings.
+ # We have no other way to set debug... debug can't be passed in
diff --git a/sys-apps/portage/files/2.1/pre8/1050_r3131_lazy_databases.patch b/sys-apps/portage/files/2.1/pre8/1050_r3131_lazy_databases.patch
new file mode 100644
index 000000000000..d8a5a0e2f61c
--- /dev/null
+++ b/sys-apps/portage/files/2.1/pre8/1050_r3131_lazy_databases.patch
@@ -0,0 +1,44 @@
+=== modified file 'pym/portage.py'
+--- pym/portage.py
++++ pym/portage.py
+@@ -6804,11 +6804,35 @@
+ global_updates()
+
+ #continue setting up other trees
+-db["/"]["porttree"] = portagetree("/")
+-db["/"]["bintree"] = binarytree("/", settings["PKGDIR"])
++class LazyDatabasesDict(dict):
++ """This class implements lazy construction of the global databases
++ db[root]["porttree"] and db[root]["bintree"]."""
++ def __init__(self, myroot, items):
++ dict.__init__(self)
++ self.update(items)
++ self.myroot = myroot
++ self.lazy_keys = ("porttree", "bintree")
++ for x in self.lazy_keys:
++ self[x] = None
++ def __getitem__(self, item_key):
++ if item_key in self.lazy_keys and item_key in self:
++ myvalue = dict.__getitem__(self, item_key)
++ if myvalue is None:
++ if "porttree" == item_key:
++ myvalue = portagetree(self.myroot)
++ elif "bintree" == item_key:
++ global settings
++ myvalue = binarytree(self.myroot, settings["PKGDIR"])
++ # The binarytree likely needs to be populated now, so we
++ # do it now to make sure that all method calls are safe.
++ myvalue.populate()
++ self[item_key] = myvalue
++ return myvalue
++ return dict.__getitem__(self, item_key)
++
++db["/"] = LazyDatabasesDict("/", db["/"])
+ if root!="/":
+- db[root]["porttree"] = portagetree(root)
+- db[root]["bintree"] = binarytree(root, settings["PKGDIR"])
++ db[root] = LazyDatabasesDict(root, db[root])
+
+ profileroots = [settings["PORTDIR"]+"/profiles/"]
+ for x in settings["PORTDIR_OVERLAY"].split():
+
diff --git a/sys-apps/portage/files/digest-portage-2.1_pre8-r1 b/sys-apps/portage/files/digest-portage-2.1_pre8-r1
new file mode 100644
index 000000000000..0766c33a8e88
--- /dev/null
+++ b/sys-apps/portage/files/digest-portage-2.1_pre8-r1
@@ -0,0 +1,3 @@
+MD5 9e46a3fdb720c1d746525f82e74c3eaa portage-2.1_pre8.tar.bz2 258150
+RMD160 4cfb15ee4fcddae8b53166a810649a98349591ea portage-2.1_pre8.tar.bz2 258150
+SHA256 b5c2d9c0af4f392b3b8e0325ad6b76d908c11ddb32019117155fb4c2ef1a6804 portage-2.1_pre8.tar.bz2 258150
diff --git a/sys-apps/portage/portage-2.1_pre8-r1.ebuild b/sys-apps/portage/portage-2.1_pre8-r1.ebuild
new file mode 100644
index 000000000000..b5e8674c7979
--- /dev/null
+++ b/sys-apps/portage/portage-2.1_pre8-r1.ebuild
@@ -0,0 +1,191 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/portage/portage-2.1_pre8-r1.ebuild,v 1.1 2006/04/11 22:15:44 zmedico Exp $
+
+inherit toolchain-funcs
+
+DESCRIPTION="The Portage Package Management System. The primary package management and distribution system for Gentoo."
+HOMEPAGE="http://www.gentoo.org/"
+SRC_URI="mirror://gentoo/${PN}-${PV}.tar.bz2 http://dev.gentoo.org/~zmedico/portage/archives/${PN}-${PV}.tar.bz2"
+LICENSE="GPL-2"
+
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc-macos ~ppc64 ~s390 ~sh ~sparc ~x86 ~x86-fbsd"
+
+SLOT="0"
+IUSE="build doc selinux"
+DEPEND=">=dev-lang/python-2.3"
+RDEPEND="!build? ( >=sys-apps/sed-4.0.5 \
+ dev-python/python-fchksum \
+ >=dev-lang/python-2.3 \
+ userland_GNU? ( sys-apps/debianutils ) \
+ >=app-shells/bash-2.05a ) \
+ elibc_glibc? ( sys-apps/sandbox )
+ elibc_uclibc? ( sys-apps/sandbox )
+ !userland_Darwin? ( >=app-misc/pax-utils-0.1.10 )
+ selinux? ( >=dev-python/python-selinux-2.15 ) \
+ doc? ( app-portage/portage-manpages )
+ >=dev-python/pycrypto-2.0.1-r4"
+
+PROVIDE="virtual/portage"
+
+S=${WORKDIR}/${PN}-${PV}
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+ local my_patches="1000_r3120_fetchlist_dict.patch
+ 1010_r3123_manifest2_fixes.patch
+ 1020_r3118_bug_121368.patch
+ 1030_r3128_bug_129559_qmerge.patch
+ 1040_r3126_bug_129244_ebuild_phase.patch
+ 1050_r3131_lazy_databases.patch"
+ local patches_dir="${PV%_*}/${PV/*_}"
+ for patch_name in ${my_patches}; do
+ einfo "Applying ${patch_name} ..."
+ patch -p0 --no-backup-if-mismatch < \
+ "${FILESDIR}"/${patches_dir}/${patch_name} >/dev/null || \
+ die "Failed to apply patch"
+ done
+ if [ "${PR}" != "r0" ]; then
+ einfo "Setting portage.VERSION to ${PVR} ..."
+ sed -i "s/^VERSION=.*/VERSION=\"${PVR}\"/" pym/portage.py || \
+ die "Failed to patch portage.VERSION"
+ fi
+}
+
+src_compile() {
+ python -O -c "import compileall; compileall.compile_dir('${S}/pym')"
+
+ cd "${S}"/src
+ $(tc-getCC) ${CFLAGS} ${LDFLAGS} -o tbz2tool tbz2tool.c || \
+ die "Failed to build tbz2tool"
+
+ if ! use userland_Darwin; then
+ cd "${S}"/src/python-missingos
+ chmod +x setup.py
+ ./setup.py build || die "Failed to build missingos module"
+ fi
+
+ if use elibc_FreeBSD; then
+ cd "${S}"/src/bsd-flags
+ chmod +x setup.py
+ ./setup.py build || die "Failed to install bsd-chflags module"
+ fi
+}
+
+src_install() {
+ cd "${S}"/cnf
+ insinto /etc
+ doins etc-update.conf dispatch-conf.conf make.globals
+ if [ -f "make.conf.${ARCH}".diff ]; then
+ patch make.conf "make.conf.${ARCH}".diff || \
+ die "Failed to patch make.conf.example"
+ newins make.conf make.conf.example
+ else
+ eerror ""
+ eerror "Portage does not have an arch-specific configuration for this arch."
+ eerror "Please notify the arch maintainer about this issue. Using generic."
+ eerror ""
+ newins make.conf make.conf.example
+ fi
+
+ if ! use userland_Darwin; then
+ cd "${S}"/src/python-missingos
+ ./setup.py install --root ${D} || \
+ die "Failed to install missingos module"
+ fi
+
+ if use elibc_FreeBSD; then
+ cd "${S}"/src/bsd-flags
+ ./setup.py install --root ${D} || \
+ die "Failed to install bsd-chflags module"
+ fi
+
+ dodir /usr/lib/portage/bin
+ exeinto /usr/lib/portage/bin
+ cd "${S}"/bin
+ doexe *
+ doexe "${S}"/src/tbz2tool
+ dosym newins /usr/lib/portage/bin/donewins
+
+ for mydir in pym pym/cache pym/elog_modules; do
+ dodir /usr/lib/portage/${mydir}
+ insinto /usr/lib/portage/${mydir}
+ cd "${S}"/${mydir}
+ doins *.py *.pyo
+ done
+
+ doman "${S}"/man/*.[0-9]
+ dodoc "${S}"/ChangeLog
+ dodoc "${S}"/NEWS
+ dodoc "${S}"/RELEASE-NOTES
+
+ dodir /usr/bin
+ for x in ebuild emerge portageq repoman tbz2tool xpak; do
+ dosym ../lib/portage/bin/${x} /usr/bin/${x}
+ done
+
+ dodir /usr/sbin
+ local my_syms="archive-conf
+ dispatch-conf
+ emaint
+ emerge-webrsync
+ env-update
+ etc-update
+ fixpackages
+ quickpkg
+ regenworld"
+ for x in ${my_syms}; do
+ dosym ../lib/portage/bin/${x} /usr/sbin/${x}
+ done
+
+ dodir /etc/portage
+ keepdir /etc/portage
+
+ doenvd "${FILESDIR}"/05portage.envd
+}
+
+pkg_preinst() {
+ if has livecvsportage ${FEATURES} && [ "${ROOT}" = "/" ]; then
+ rm -rf ${IMAGE}/usr/lib/portage/pym/*
+ mv ${IMAGE}/usr/lib/portage/bin/tbz2tool ${T}
+ rm -rf ${IMAGE}/usr/lib/portage/bin/*
+ mv ${T}/tbz2tool ${IMAGE}/usr/lib/portage/bin/
+ else
+ for mydir in pym pym/cache pym/elog_modules; do
+ rm /usr/lib/portage/${mydir}/*.pyc >& /dev/null
+ rm /usr/lib/portage/${mydir}/*.pyo >& /dev/null
+ done
+ fi
+}
+
+pkg_postinst() {
+ local x
+
+ if [ ! -f "${ROOT}/var/lib/portage/world" ] &&
+ [ -f ${ROOT}/var/cache/edb/world ] &&
+ [ ! -h ${ROOT}/var/cache/edb/world ]; then
+ mv ${ROOT}/var/cache/edb/world ${ROOT}/var/lib/portage/world
+ ln -s ../../lib/portage/world /var/cache/edb/world
+ fi
+
+ for x in ${ROOT}etc/._cfg????_make.globals; do
+ # Overwrite the globals file automatically.
+ [ -e "${x}" ] && mv -f "${x}" "${ROOT}etc/make.globals"
+ done
+
+ ewarn "This series contains a completely rewritten caching framework."
+ ewarn "If you are using any cache modules (such as the CDB cache"
+ ewarn "module) portage will not work until they have been disabled."
+ echo
+ einfo "The default cache format has changed between 2.0.x and 2.1"
+ einfo "versions. If you have upgraded from 2.0.x, before using"
+ einfo "emerge, run \`emerge --metadata\` to restore portage's local"
+ einfo "cache."
+ echo
+ einfo "Flag ordering has changed for \`emerge --pretend --verbose\`."
+ einfo "Add EMERGE_DEFAULT_OPTS=\"--alphabetical\" to /etc/make.conf"
+ einfo "to restore the previous ordering."
+ echo
+ einfo "See NEWS and RELEASE-NOTES for further changes."
+}