Fix manifest/digest generation logic for bug #129737.
authorZac Medico <zmedico@gentoo.org>
Thu, 13 Apr 2006 03:50:43 +0000 (03:50 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 13 Apr 2006 03:50:43 +0000 (03:50 -0000)
svn path=/main/trunk/; revision=3136

pym/portage.py
pym/portage_manifest.py

index 8c9584ea2fc6a178781d512c701a84a8fcc0e471..413bd4cd95dbb0302f5f3f9999ccc25f0593652b 100644 (file)
@@ -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):
index 6a855bb0895a4fa399ee5b469d201c2db2411d07..491074da9a5af38d2fbadc453e745a46a32e1b2d 100644 (file)
@@ -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]