Add a --force option for `ebuild digest` so that the user doesn't have to manually...
authorZac Medico <zmedico@gentoo.org>
Mon, 31 Jul 2006 15:55:15 +0000 (15:55 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 31 Jul 2006 15:55:15 +0000 (15:55 -0000)
svn path=/main/branches/2.1/; revision=4060

bin/ebuild
pym/portage_manifest.py

index a62585a5eaf77fc6e25606e4c422a38235753a4a..e6819b9dabd6d088d2056b129c1694a479290d9a 100755 (executable)
@@ -12,9 +12,9 @@ if len(sys.argv) <= 2:
        sys.exit(1)
 
 
-(opts, pargs) = getopt.getopt(sys.argv[1:], '', ['debug'])
+opts, pargs = getopt.getopt(sys.argv[1:], '', ['debug', 'force'])
 debug = ("--debug",'') in opts
-
+force = ("--force",'') in opts
 
 if "merge" in pargs:
        print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
@@ -79,10 +79,33 @@ if len(pargs) > 1 and "config" in pargs:
        print "config must be called on it's own, not combined with any other phase"
        sys.exit(1)
 
+def discard_digests(myebuild, mysettings, mydbapi):
+       """Discard all distfiles digests for the given ebuild.  This is useful when
+       upstream has changed the identity of the distfiles and the user would
+       otherwise have to manually remove the Manifest and files/digest-* files in
+       order to ensure correct results."""
+       pkgdir = os.path.dirname(myebuild)
+       fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
+       cat, pkg = pkgdir.split(os.sep)[-2:]
+       cpv = cat + "/" + os.path.basename(myebuild)[:-7]
+       from portage_manifest import Manifest
+       mf = Manifest(pkgdir, mysettings["DISTDIR"],
+               fetchlist_dict=fetchlist_dict)
+       mf.create(requiredDistfiles=None,
+               assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
+       distfiles = fetchlist_dict[cpv]
+       for myfile in distfiles:
+               try:
+                       del mf.fhashdict["DIST"][myfile]
+               except KeyError:
+                       pass
+       mf.write()
 
 for arg in pargs:
        try:
                tmpsettings = portage.config(clone=portage.settings)
+               if arg == "digest" and force:
+                       discard_digests(ebuild, tmpsettings, portage.portdb)
                a = portage.doebuild(ebuild, arg, portage.root, tmpsettings, debug=debug, cleanup=("noauto" not in portage.features), tree=mytree)
        except KeyboardInterrupt:
                print "Interrupted."
index ee9b4b8331ea8edd66aa31d9d46b208d7094ea37..687d7ca103966db5351a1cc0c8d19dd69a078124 100644 (file)
@@ -219,15 +219,14 @@ 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
+                       missing_digests = set()
                        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
+                                       missing_digests.add(f)
+                       if missing_digests:
+                               # This allows us to force remove of stale digests for the
+                               # ebuild --force digest option.
+                               distlist = [f for f in distlist if f not in missing_digests]
                        update_digest = True
                        if not force:
                                try:
@@ -236,13 +235,15 @@ class Manifest(object):
                                        f.close()
                                        if len(old_data) == 1 and "DIST" in old_data:
                                                new_data = self._getDigestData(distlist)
-                                               for myfile in new_data["DIST"]:
-                                                       for hashname in new_data["DIST"][myfile].keys():
-                                                               if hashname != "size" and \
-                                                               hashname not in portage_const.MANIFEST1_HASH_FUNCTIONS:
-                                                                       del new_data["DIST"][myfile][hashname]
-                                               if new_data["DIST"] == old_data["DIST"]:
-                                                       update_digest = False
+                                               if "DIST" in new_data:
+                                                       for myfile in new_data["DIST"]:
+                                                               for hashname in \
+                                                                       new_data["DIST"][myfile].keys():
+                                                                       if hashname != "size" and hashname not in \
+                                                                               portage_const.MANIFEST1_HASH_FUNCTIONS:
+                                                                               del new_data["DIST"][myfile][hashname]
+                                                       if new_data["DIST"] == old_data["DIST"]:
+                                                               update_digest = False
                                except (IOError, OSError), e:
                                        if errno.ENOENT == e.errno:
                                                pass
@@ -402,7 +403,7 @@ class Manifest(object):
                return None
        
        def create(self, checkExisting=False, assumeDistHashesSometimes=False,
-               assumeDistHashesAlways=False, requiredDistfiles=None):
+               assumeDistHashesAlways=False, requiredDistfiles=[]):
                """ Recreate this Manifest from scratch.  This will not use any
                existing checksums unless assumeDistHashesSometimes or
                assumeDistHashesAlways is true (assumeDistHashesSometimes will only
@@ -444,7 +445,11 @@ class Manifest(object):
                distlist = set()
                for cpv in cpvlist:
                        distlist.update(self._getCpvDistfiles(cpv))
-               if requiredDistfiles is None or len(requiredDistfiles) == 0:
+               if requiredDistfiles is None:
+                       # This allows us to force removal of stale digests for the
+                       # ebuild --force digest option (no distfiles are required).
+                       requiredDistfiles = set()
+               elif len(requiredDistfiles) == 0:
                        # repoman passes in an empty list, which implies that all distfiles
                        # are required.
                        requiredDistfiles = distlist.copy()