From d3caafb7be8bf00185d13b55046f0362ccbfc62d Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 13 Apr 2006 03:50:43 +0000 Subject: Fix manifest/digest generation logic for bug #129737. svn path=/main/trunk/; revision=3136 --- pym/portage.py | 35 +++++++++++------------------------ pym/portage_manifest.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/pym/portage.py b/pym/portage.py index 8c9584ea2..413bd4cd9 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -2078,33 +2078,20 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks", return 1 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. + """Generates a digest file if missing. Assumes all files are available. DEPRECATED: this now only is a compability wrapper for - portage_manifest.Manifest()""" - - # NOTE: manifestonly is useless with manifest2 and therefore ignored - # NOTE: the old code contains a lot of crap that should really be elsewhere - # (e.g. cvs stuff should be in ebuild(1) and/or repoman) - # TODO: error/exception handling - + portage_manifest.Manifest() + NOTE: manifestonly and overwrite are useless with manifest2 and + are therefore ignored.""" 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 - writemsg(">>> Creating Manifest for %s\n" % mysettings["O"]) - try: - writemsg(">>> Adding digests for file %s\n" % 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 - # NOTE: overwrite=0 is only used by emerge --digest, not sure we wanna keep that - if overwrite or not os.path.exists(mf.getFullname()): - mf.write(sign=False) - + writemsg(">>> Creating Manifest for %s\n" % mysettings["O"]) + try: + mf.create(assumeDistfileHashes=True, requiredDistfiles=myarchives) + except portage_exception.FileNotFound, e: + writemsg("!!! File %s doesn't exist, can't update Manifest\n" % str(e)) + return 0 + mf.write(sign=False) return 1 def digestParseFile(myfilename, mysettings=None): diff --git a/pym/portage_manifest.py b/pym/portage_manifest.py index 6a855bb08..491074da9 100644 --- a/pym/portage_manifest.py +++ b/pym/portage_manifest.py @@ -3,7 +3,8 @@ # $Header: $ import errno, os, sets -from itertools import imap +if not hasattr(__builtins__, "set"): + from sets import Set as set import portage_exception, portage_versions, portage_const from portage_checksum import * @@ -135,6 +136,15 @@ class Manifest(object): for cpv in cpvlist: dname = os.path.join(self.pkgdir, "files", "digest-%s" % self._catsplit(cpv)[1]) distlist = self._getCpvDistfiles(cpv) + have_all_checksums = True + for f in distlist: + if f not in self.fhashdict["DIST"] or len(self.fhashdict["DIST"][f]) == 0: + have_all_checksums = False + break + if not have_all_checksums: + # We don't have all the required checksums to generate a proper + # digest, so we have to skip this cpv. + continue update_digest = True if not force: try: @@ -275,10 +285,13 @@ class Manifest(object): return t return None - def create(self, checkExisting=False, assumeDistfileHashes=True): + def create(self, checkExisting=False, assumeDistfileHashes=True, requiredDistfiles=None): """ Recreate this Manifest from scratch, not using any existing checksums (exception: if assumeDistfileHashes is true then existing DIST checksums are - reused if the file doesn't exist in DISTDIR.""" + reused if the file doesn't exist in DISTDIR. The requiredDistfiles + parameter specifies a list of distfiles to raise a FileNotFound + exception for (if no file or existing checksums are available), and + defaults to all distfiles when not specified.""" if checkExisting: self.checkAllHashes() if assumeDistfileHashes: @@ -308,18 +321,21 @@ class Manifest(object): 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 = [] + distlist = set() for cpv in cpvlist: - distlist.extend(self._getCpvDistfiles(cpv)) + distlist.update(self._getCpvDistfiles(cpv)) + if requiredDistfiles is None or len(requiredDistfiles) == 0: + # repoman passes in an empty list, which implies that all distfiles + # are required. + requiredDistfiles = distlist.copy() for f in distlist: 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: self.fhashdict["DIST"][f] = distfilehashes[f] - else: - raise FileNotFound(fname) - + elif f in requiredDistfiles: + raise FileNotFound(fname) def _pkgdir_category(self): return self.pkgdir.rstrip(os.sep).split(os.sep)[-2] -- cgit v1.2.3-1-g7c22