#!/usr/bin/env python # Copyright 2003-2005 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ # THANKS: # The starting point ideas were found here: # http://forums.gentoo.org/viewtopic.php?t=3011 # Thanks to eswanson and far for their contributions, and to wolf31o2 for his # support. Thanks also to karltk, some of this code was at some point inspired # by his "equery" tool. And thanks to people who had a look on bug #33877: # Benjamin Braatz, fuzzyray, genone, etc. # TODO: # - exclusion file syntax could be improved (maybe it should support real # dep-atoms, or wildcards, etc.) # - some policy to keep the X latest versions of a package (in each of its # SLOT maybe) would be really cool... # - add an option to protect system binary packages # => yup, but later... (needs some portage modifications to be done right) # - add actions for PORT_LOGDIR and/or /var/tmp/portage cleaning? # => bah, don't know... imho tmpreaper or find+rm onliners are enough here # - cleanup of DISTDIR/cvs-src when action=distfiles # => i never use cvs ebuilds, i should check what it does exactly # - rewrite for a decent Portage API if there ever is one # ChangeLog: # 0.4 --> 0.4.1 # - added support for some "eclean-dist" and "eclean-pkg" symlinks on "eclean" # (and thus refactored command-line parsing and help screen code) # - accept file names in exclude files for specific distfiles protection # (useful to protect the OOo i18n files for instance, which are not in # $SRC_URI but put there manually) # - minor rewrite of some findDistfiles() code # - added /usr/lib/portage/pym python path, just to be sure it comes first # (after all, "ouput" is a pretty generic name for a python module...) # 0.2 --> 0.4 # - added exclusion files support # - added time limit option # - added size limit option (for distfiles only) # - added fetch-restricted distfile optionnal protection # - added --package-names option for protection of all versions of installed # packages # - removed support of multiple actions on command-line. That would have been # hell with action-specific options. # BUGS: # No real bug found yet, see TODO for stuffs which could be improved/modified. ############################################################################### # Meta: __author__ = "Thomas de Grenier de Latour (tgl)" __email__ = "degrenier@easyconnect.fr" __version__ = "0.4.1" __productname__ = "eclean" __description__ = "A cleaning tool for Gentoo distfiles and binaries." ############################################################################### # Python imports: import sys import os, stat import string, re import time import getopt import fpformat import signal sys.path.insert(0,'/usr/lib/portage/pym') import portage from output import * # Ignominous CVS / non-CVS compatibility hacks: if portage.VERSION[:6] == '2.0.51': listdir = portage.listdir # else, assume it's a reasonably recent CVS (or future 2.1) else: from portage_file import listdir ############################################################################### # Misc. shortcuts to some portage stuff: port_settings = portage.settings distdir = port_settings["DISTDIR"] pkgdir = port_settings["PKGDIR"] ############################################################################### # printVersion: def printVersion(): print "%s (version %s) - %s" \ % (__productname__, __version__, __description__) print "Author: %s <%s>" % (__author__,__email__) print "Copyright 2003-2005 Gentoo Foundation" print "Distributed under the terms of the GNU General Public License v2" ############################################################################### # printUsage: print help message. May also print partial help to stderr if an # error from {'options','actions'} is specified. def printUsage(error=None,help=None): out = sys.stdout if error: out = sys.stderr if not error in ('actions', 'global-options', \ 'packages-options', 'distfiles-options', \ 'merged-packages-options', 'merged-distfiles-options', \ 'time', 'size'): error = None if not error and not help: help = 'all' if error == 'time': eerror("Wrong time specification") print >>out, "Time specification should be an integer followed by a"+ \ " single letter unit." print >>out, "Available units are: y (years), m (months), w (weeks), "+ \ "d (days) and h (hours)." print >>out, "For instance: \"1y\" is \"one year\", \"2w\" is \"two"+ \ " weeks\", etc. " return if error == 'size': eerror("Wrong size specification") print >>out, "Size specification should be an integer followed by a"+ \ " single letter unit." print >>out, "Available units are: G, M, K and B." print >>out, "For instance: \"10M\" is \"ten megabytes\", \"200K\" "+ \ "is \"two hundreds kilobytes\", etc." return if error in ('global-options', 'packages-options', 'distfiles-options', \ 'merged-packages-options', 'merged-distfiles-options',): eerror("Wrong option on command line.") print >>out elif error == 'actions': eerror("Wrong or missing action name on command line.") print >>out print >>out, white("Usage:") if error in ('actions','global-options', 'packages-options', \ 'distfiles-options') or help == 'all': print >>out, " "+turquoise(__productname__), \ yellow("[global-option] ..."), \ green(""), \ yellow("[action-option] ...") if error == 'merged-distfiles-options' or help in ('all','distfiles'): print >>out, " "+turquoise(__productname__+'-dist'), \ yellow("[global-option, distfiles-option] ...") if error == 'merged-packages-options' or help in ('all','packages'): print >>out, " "+turquoise(__productname__+'-pkg'), \ yellow("[global-option, packages-option] ...") if error in ('global-options', 'actions'): print >>out, " "+turquoise(__productname__), \ yellow("[--help, --version]") if help == 'all': print >>out, " "+turquoise(__productname__+"(-dist,-pkg)"), \ yellow("[--help, --version]") if error == 'merged-packages-options' or help == 'packages': print >>out, " "+turquoise(__productname__+'-pkg'), \ yellow("[--help, --version]") if error == 'merged-distfiles-options' or help == 'distfiles': print >>out, " "+turquoise(__productname__+'-dist'), \ yellow("[--help, --version]") print >>out if error in ('global-options', 'merged-packages-options', \ 'merged-distfiles-options') or help: print >>out, "Available global", yellow("options")+":" print >>out, yellow(" -C, --nocolor")+ \ " - turn off colors on output" print >>out, yellow(" -d, --destructive")+ \ " - only keep the minimum for a reinstallation" print >>out, yellow(" -e, --exclude-file=")+ \ " - path to the exclusion file" print >>out, yellow(" -i, --interactive")+ \ " - ask confirmation before deletions" print >>out, yellow(" -n, --package-names")+ \ " - protect all versions (when --destructive)" print >>out, yellow(" -p, --pretend")+ \ " - only display what would be cleaned" print >>out, yellow(" -q, --quiet")+ \ " - be as quiet as possible" print >>out, yellow(" -t, --time-limit=