#!/usr/bin/env python # # gentoo-slotcheck.py # Author: CJ Kucera # URL: http://apocalyptech.com/software/gentoo # # This script is designed to help clean up your Gentoo package # installation database. Portage has a concept of SLOTs that # enable different versions of packages to exist side-by-side. # More information on SLOTs can be found at: # http://gentoo.org/doc/portage-manual.html # # The early "skeleton" ebuild file, upon which many ebuilds were # written, did not have a default SLOT defined, or it was blank. # As ebuilds were revised, SLOT values were put in, but because # the original versions had a blank SLOT, the newer versions # existed side-by-side with the previous versions. For instance, # on my machine right now, I've got app-admin/chkrootkit version # 0.35 and version 0.36. 0.35 has a blank SLOT, whereas 0.36 # has a SLOT of zero. There's no reason to keep around the # older version, but there it will sit until manually removed. # Doing an "emerge clean" has no effect on SLOT-less packages. # # It should be noted that these extra versions really aren't # that big of a deal, because "side-by-side" in this case # is fairly meaningless; the new version is installed basically # on top of the old version. Still, old libraries can be kept # around, stray files CAN cause confusion, and if you're a # system-organizing freak like me, it'll bug you. But if you # want to make sure that you don't break things, and the # lingering versions don't bother you, then you can pretty # much ignore this script. # # If you feel like cleaning up your Portage tree by hand, you # can do so by glancing around inside /var/db/pkg, but this # script is designed to make it a bit easier. It will scan # through that directory and notice any program that's # installed twice. If one of those installations has a blank # SLOT defined, it'll ask you if you'd like to remove that # version. If you say yes, it will first show you everything # that depends on the program you're about to destroy (just # so you're extra careful here), and also the output of # "emerge --pretend unmerge ", so that you know what's # about to happen to your system. If you're okay with what # was displayed, say Yes again, and it'll do the work for you. # # Note that while this program SHOULDN'T do anything nasty to # your system, there's a chance that it'll erase your hard # drive, fry your CPU, poison your cat, default your mortgage, # promote racial hatred, and cause our sun to implode in on # itself. If you're uncomfortable about removing some package, # then don't. Again, it's typically not that big of a deal. # Use with care and caution, and I'M NOT RESPONSIBLE! # # I'll hereby release this thing under the GPL, in case anyone # cares. See http://www.gnu.org/licenses/gpl.txt for details. # # Lastly, if anyone deems this script worthy of improvement, # go for it. It could certainly use some. :) # # Version History: # 2002.09.13 - CJ Kucera # Initial release # 2002.09.13 - CJ Kucera # Consolidated a couple of loops (minor) # # TODO: # * Seeing as "emerge" is written in Python, it would probably # make sense to just call its functions in here, instead of # spawning off a new Python process. # * I'm aware that system() is far less secure than exec*() # or spawn*() or any other function that more rigidly defines # argument input. # import os,sys,portage installcache = portage.db["/"]["vartree"] for package in installcache.getallnodes(): versions = installcache.getnode(package) if (len(versions) > 1): blankslots=[] totalversions=[] for version in versions: slot = installcache.getslot(version[0]) version.append(slot) if (slot == ""): blankslots.append(version[0]) if (len(blankslots) > 0): print "------------------------" print print "Package " + package + " has a SLOT mismatch:" print for version in versions: print " * " + version[0] + " has a SLOT of '" + version[2] + "'" print print "The following versions will be unmerged:" print unmergelist = "" for blank in blankslots: print " * " + blank unmergelist = unmergelist + blank + " " print sys.stdout.write("Do the unmerge [N/y/q]? ") dounmerge = sys.stdin.readline() print if (dounmerge[0].lower() == "y"): print "First we'll check qpkg and --pretend to make sure things are kosher . . ." print os.system("qpkg -q " + unmergelist) print os.system("emerge --pretend unmerge " + unmergelist) print sys.stdout.write("Still do the unmerge [N/y/q]? ") dounmerge = sys.stdin.readline() print if (dounmerge[0].lower() == "y"): print "Okay, here we go." os.system("emerge unmerge " + unmergelist) elif (dounmerge[0].lower() == "q"): sys.exit() else: print "Maybe next time, then." elif (dounmerge[0].lower() == "q"): sys.exit() else: print "We'll skip that one for now, then." print # The End