summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-07-31 15:55:15 +0000
committerZac Medico <zmedico@gentoo.org>2006-07-31 15:55:15 +0000
commit994b6ec1c4d71a1a01038e79caa29d8b13deac80 (patch)
tree2f2f706d2f27e68908713d441dc49d68dd8952cc
parent7bad0643f772a1fdf5cfa7c49c8ae30232600550 (diff)
downloadportage-994b6ec1c4d71a1a01038e79caa29d8b13deac80.tar.gz
portage-994b6ec1c4d71a1a01038e79caa29d8b13deac80.tar.bz2
portage-994b6ec1c4d71a1a01038e79caa29d8b13deac80.zip
Add a --force option for `ebuild digest` so that the user doesn't have to manually remove the Manifest and files/digest-* files when upstream changes the identity of distfiles. See bug #141843. This patch is from trunk r4040:4043 and r4044:4046.
svn path=/main/branches/2.1/; revision=4060
-rwxr-xr-xbin/ebuild27
-rw-r--r--pym/portage_manifest.py37
2 files changed, 46 insertions, 18 deletions
diff --git a/bin/ebuild b/bin/ebuild
index a62585a5e..e6819b9da 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -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."
diff --git a/pym/portage_manifest.py b/pym/portage_manifest.py
index ee9b4b833..687d7ca10 100644
--- a/pym/portage_manifest.py
+++ b/pym/portage_manifest.py
@@ -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()