unmerge: remove generated info "dir" files
authorZac Medico <zmedico@gentoo.org>
Thu, 4 Aug 2011 23:09:36 +0000 (16:09 -0700)
committerZac Medico <zmedico@gentoo.org>
Thu, 4 Aug 2011 23:09:36 +0000 (16:09 -0700)
These files are generated by emerge, so we need to remove them
when they are the only thing left in the directory. This will fix
bug #323213.

pym/portage/dbapi/vartree.py

index db44491f2ec771ba73ed296287743526f3b5e445..94b7936e538d196378c559971f783f9e6472b0b8 100644 (file)
@@ -1985,6 +1985,22 @@ class dblink(object):
                        real_root_len = len(real_root) - 1
                        eroot_split_len = len(self.settings["EROOT"].split(os.sep)) - 1
 
+                       # These files are generated by emerge, so we need to remove
+                       # them when they are the only thing left in a directory.
+                       infodir_cleanup = frozenset(["dir", "dir.old"])
+                       infodirs = frozenset(infodir for infodir in chain(
+                               self.settings.get("INFOPATH", "").split(":"),
+                               self.settings.get("INFODIR", "").split(":")) if infodir)
+                       infodirs_inodes = set()
+                       for infodir in infodirs:
+                               infodir = os.path.join(real_root, infodir.lstrip(os.sep))
+                               try:
+                                       statobj = os.stat(infodir)
+                               except OSError:
+                                       pass
+                               else:
+                                       infodirs_inodes.add((statobj.st_dev, statobj.st_ino))
+
                        for i, objkey in enumerate(mykeys):
 
                                obj = normalize_path(objkey)
@@ -2204,6 +2220,30 @@ class dblink(object):
                        mydirs.reverse()
 
                        for obj, inode_key in mydirs:
+                               if inode_key in infodirs_inodes:
+                                       try:
+                                               remaining = os.listdir(obj)
+                                       except OSError:
+                                               pass
+                                       else:
+                                               cleanup_info_dir = ()
+                                               if remaining and \
+                                                       len(remaining) <= len(infodir_cleanup):
+                                                       if not set(remaining).difference(infodir_cleanup):
+                                                               cleanup_info_dir = remaining
+
+                                               for child in cleanup_info_dir:
+                                                       child = os.path.join(obj, child)
+                                                       try:
+                                                               lstatobj = os.lstat(child)
+                                                               if stat.S_ISREG(lstatobj.st_mode):
+                                                                       unlink(child, lstatobj)
+                                                                       show_unmerge("<<<", "", "obj", child)
+                                                       except EnvironmentError as e:
+                                                               if e.errno not in ignored_unlink_errnos:
+                                                                       raise
+                                                               del e
+                                                               show_unmerge("!!!", "", "obj", child)
                                try:
                                        if bsd_chflags:
                                                lstatobj = os.lstat(obj)