Add a sanity check in dblink.treewalk() so that a broken ebuild
authorZac Medico <zmedico@gentoo.org>
Wed, 28 Nov 2007 03:45:40 +0000 (03:45 -0000)
committerZac Medico <zmedico@gentoo.org>
Wed, 28 Nov 2007 03:45:40 +0000 (03:45 -0000)
that doesn't install any files will not be able to replace a
package in the same slot that really installs files.

This check can be bypassed by manually unmerging the old package
or by setting PORTAGE_PACKAGE_EMPTY_ABORT="0" in /etc/make.conf.

svn path=/main/trunk/; revision=8720

pym/portage/dbapi/vartree.py

index 89753f39c63b57e10f24c435997eccd1c724ce2b..29019a53b7e71907183d51e492580da9e84c5ec2 100644 (file)
@@ -1716,6 +1716,11 @@ class dblink(object):
                if slot is None:
                        slot = ""
 
+               from portage.elog.messages import eerror as _eerror
+               def eerror(lines):
+                       for l in lines:
+                               _eerror(l, phase="preinst", key=self.settings.mycpv)
+
                if slot != self.settings["SLOT"]:
                        writemsg("!!! WARNING: Expected SLOT='%s', got '%s'\n" % \
                                (self.settings["SLOT"], slot))
@@ -1781,6 +1786,42 @@ class dblink(object):
                                        # to an infinite recursion loop.
                                        mylinklist.append(file_path[len(srcroot):])
 
+               # If there are no files to merge, and an installed package in the same
+               # slot has files, it probably means that something went wrong.
+               if self.settings.get("PORTAGE_PACKAGE_EMPTY_ABORT") != "0" and \
+                       not myfilelist and not mylinklist and others_in_slot:
+                       installed_files = None
+                       for other_dblink in others_in_slot:
+                               installed_files = other_dblink.getcontents()
+                               if not installed_files:
+                                       continue
+                               from textwrap import wrap
+                               wrap_width = 72
+                               msg = []
+                               d = (
+                                       self.mycpv,
+                                       other_dblink.mycpv
+                               )
+                               msg.extend(wrap(("The '%s' package will not install " + \
+                                       "any files, but the currently installed '%s'" + \
+                                       " package has the following files: ") % d, wrap_width))
+                               msg.append("")
+                               msg.extend(sorted(installed_files))
+                               msg.append("")
+                               msg.append("package %s NOT merged" % self.mycpv)
+                               msg.append("")
+                               msg.extend(wrap(
+                                       ("Manually run `emerge --unmerge =%s` " % \
+                                       other_dblink.mycpv) + "if you really want to " + \
+                                       "remove the above files. Set " + \
+                                       "PORTAGE_PACKAGE_EMPTY_ABORT=\"0\" in " + \
+                                       "/etc/make.conf if you do not want to " + \
+                                       "abort in cases like this.",
+                                       wrap_width))
+                               eerror(msg)
+                       if installed_files:
+                               return 1
+
                # Preserve old libs if they are still in use
                if slot_matches and "preserve-libs" in self.settings.features:
                        self._preserve_libs(srcroot, destroot, myfilelist+mylinklist, counter)
@@ -1797,11 +1838,6 @@ class dblink(object):
                        self.settings, 0, 0, mydbapi)
                prepare_build_dirs(destroot, self.settings, cleanup)
 
-               from portage.elog.messages import eerror as _eerror
-               def eerror(lines):
-                       for l in lines:
-                               _eerror(l, phase="preinst", key=self.settings.mycpv)
-
                if collisions:
                        collision_protect = "collision-protect" in self.settings.features
                        msg = "This package will overwrite one or more files that" + \