Difference between revisions of "CacheClean"

From ArchWiki
Jump to: navigation, search
(File name pattern adjusted to correctly match things like "libjpeg-8-2-i686.pkg.tar.gz".)
(Code: updated link to new github repo)
(18 intermediate revisions by 7 users not shown)
Line 1: Line 1:
[[Category:Scripts (English)]]
+
[[Category:Scripts]]
[[Category:Package management (English)]]
+
[[Category:Package management]]
<pre>
+
[[zh-CN:CacheClean]]
#!/usr/bin/env python
+
Cacheclean is python script to clean {{ic|/var/cache/pacman/pkg}} allowing users to specify how many package versions should be retained. In function, it is similar to {{ic|pacman -Sc}} except users select how many old versions to keep. Another difference is unlike, {{ic|pacman -Sc}} cacheclean does not discriminate against packages that are not currently installed as it inspects {{ic|/var/cache/pacman/pkg}}.
"""cache_clean - a simple python script to clean up the /var/cache/pacman/pkg directory.
+
More versatile than 'pacman -Sc' in that you can select how many old versions
+
to keep.
+
Usage: cache_clean {-p} {-v} <# of copies to keep>
+
  # of copies to keep - (required) how many generations of each package to keep
+
  -p - (optional) preview what would be deleted; forces verbose (-v) mode.
+
  -v - (optional) show deleted packages."""
+
# Note that the determination of package age is done by simply looking at the date-time
+
# modified stamp on the file. There is just enough variation in the way package version
+
# is done that I thought this would be simpler & just as good.
+
# Also note that you must be root to run this script.
+
  
import getopt
+
== Installation ==
import os
+
[[AUR]] package: {{AUR|cacheclean}}
import re
+
import sys
+
  
# helper function to get tuple of (file dtm, file name, file sz)
+
== Usage ==
def fn_stats(fn):
+
  s = os.stat(fn)
+
  return (s.st_mtime, fn, s.st_size)
+
  
# cleanup does the actual pkg file deletion
+
{{bc|cacheclean {-p} {-v} <# of copies to keep>
def cleanup(run_list):
+
# of copies to keep - (required) how many generations of each package to keep
  # strictly speaking only the first two of these globals need to be listed.
+
-p - (optional) preview what would be deleted; forces verbose (-v) mode.
  global n_deleted, bytes_deleted, opt_verbose, opt_preview, n_to_keep
+
-v - (optional) show deleted packages.}}
  # return if the run_list is too short
+
  #print run_list
+
  #return
+
  if len(run_list) <= n_to_keep: return
+
  # Build list of tuples (date-time file modified, file name, file size)
+
  dtm_list = [fn_stats(tfn) for tfn in run_list]
+
  # Sort the list by date-time
+
  dtm_list.sort()
+
  # Build list of the filenames to delete (all but last n_to_keep).
+
  # <showing_off>
+
  #kill_list = [tfn[1] for tfn in dtm_list[:-n_to_keep]]
+
  #bytes_deleted = sum(x[2] for x in dtm_list[:-n_to_keep])
+
  # </showing_off>
+
  kill_list = []
+
  for x in dtm_list[:-n_to_keep]:
+
    kill_list.append(x[1])
+
    bytes_deleted += x[2]
+
  if opt_verbose: print kill_list
+
  n_deleted += len(kill_list)
+
  # and finally delete (if not in preview mode)
+
  if not opt_preview:
+
    for dfn in kill_list:
+
      os.unlink(dfn)
+
  
######################################################################
+
== Code ==
# mainline processing
+
For those wishing to contribute, the script's source code is hosted in [https://github.com/graysky2/cacheclean/tree/master/cacheclean this github repository].  To simplify updates, please fork and send a pull request with updates/changes.
  
# process command line options
+
== See also ==
try:
+
*Author's original forum thread: [http://bbs.archlinux.org/viewtopic.php?id=9104 A utility for cleaning /var/cache/pacman/pkg]
  opts, pargs = getopt.getopt(sys.argv[1:], 'vp')
+
  opt_dict = dict(opts)
+
  opt_preview = '-p' in opt_dict
+
  opt_verbose = '-v' in opt_dict
+
  if opt_preview: opt_verbose = True
+
  if len(pargs) == 1:
+
    n_to_keep = pargs[0]
+
  else:
+
    raise getopt.GetoptError("missing required argument.")
+
  try:
+
    n_to_keep = int(n_to_keep)
+
    if n_to_keep <= 0: raise ValueError
+
  except ValueError, e:
+
    raise getopt.GetoptError("# of copies to keep must be numeric > 0!")
+
except getopt.GetoptError, msg:
+
  print "Error:",msg,"\n",__doc__
+
  sys.exit(1)
+
 
+
# change to the pkg directory & get a sorted list of its contents
+
os.chdir('/var/cache/pacman/pkg')
+
pkg_fns = os.listdir('.')
+
pkg_fns.sort()
+
 
+
# Pattern to use to extract the package name from the tar file name:
+
# for pkg e.g. 'gnome-common-2.8.0-1-i686.pkg.tar.gz' group(1) is 'gnome-common'.
+
bpat = re.compile(r'^(.+?)(?:-\d.*?)(-i686|-x86_64|-any)?\.pkg\.tar\.(?:gz|xz)$')
+
 
+
n_deleted = 0
+
bytes_deleted = 0
+
pkg_base_nm = ''
+
# now look for "runs" of the same package name differing only in version info.
+
for run_end in range(len(pkg_fns)):
+
  fn = pkg_fns[run_end]
+
 
+
  # make sure we skip directories
+
  if not os.path.isdir(fn):
+
    mo = bpat.match(fn) # test for a match of the package name pattern
+
    if mo:
+
      tbase = mo.group(1) # gets the 'base' package name
+
      # include the architecture in the name if it's present
+
      if mo.lastindex > 1:
+
        tbase += mo.group(2)
+
      #print 'tbase: ',tbase,'  ',mo.lastindex
+
      # is it a new base name, i.e. the start of a new run?
+
      if tbase != pkg_base_nm: # if so then process the prior run
+
        if pkg_base_nm != '':
+
          cleanup(pkg_fns[run_start:run_end])
+
        pkg_base_nm = tbase # & setup for the new run
+
        run_start = run_end
+
    else:
+
      print >>sys.stderr, "File '"+fn+"' doesn't match package pattern!"
+
  else:
+
    print >>sys.stdout, "skipping directory '"+fn+"'!"
+
 
+
# catch the final run of the list
+
run_end += 1
+
cleanup(pkg_fns[run_start:run_end])
+
 
+
if opt_verbose:
+
  if opt_preview:
+
    print "Preview mode (no files deleted):",
+
  print n_deleted,"files deleted,",bytes_deleted/1000,"kbytes."
+
</pre>
+

Revision as of 14:00, 4 August 2012

Cacheclean is python script to clean /var/cache/pacman/pkg allowing users to specify how many package versions should be retained. In function, it is similar to pacman -Sc except users select how many old versions to keep. Another difference is unlike, pacman -Sc cacheclean does not discriminate against packages that are not currently installed as it inspects /var/cache/pacman/pkg.

Installation

AUR package: cachecleanAUR

Usage

cacheclean {-p} {-v} <# of copies to keep>
	# of copies to keep - (required) how many generations of each package to keep
	-p - (optional) preview what would be deleted; forces verbose (-v) mode.
	-v - (optional) show deleted packages.

Code

For those wishing to contribute, the script's source code is hosted in this github repository. To simplify updates, please fork and send a pull request with updates/changes.

See also