[Treepkg-commits] r505 - trunk/contrib/bin
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Tue Jan 11 18:20:02 CET 2011
Author: teichmann
Date: 2011-01-11 18:20:02 +0100 (Tue, 11 Jan 2011)
New Revision: 505
Added:
trunk/contrib/bin/copy-latest-pkgs.py
Modified:
trunk/contrib/bin/README
Log:
contrib: Added copy-latest-pkgs.py to copy/hardlink latest
packages from the mill to the next higher attention level.
Modified: trunk/contrib/bin/README
===================================================================
--- trunk/contrib/bin/README 2011-01-11 16:27:02 UTC (rev 504)
+++ trunk/contrib/bin/README 2011-01-11 17:20:02 UTC (rev 505)
@@ -17,3 +17,19 @@
-v, --verbose verbose output
-d, --dry-run don't remove the old deb files
-k KEEP, --keep=KEEP number of files to keep. Default: 3
+
+
+copy-latest-pkgs.py
+-------------------
+Copies/Hardlinks deb files from snapshots to experimental.
+It performs a check if you run it as user 'saegewerker'.
+By default the files are hardlinked.
+
+Usage: copy-latest-pkgs.py [options] src-dir dst-dir
+
+Options:
+ -h, --help show this help message and exit
+ -v, --verbose verbose output
+ -d, --dry-run don't copy the deb files
+ -n, --no-saegewerker Don't force run as 'saegewerker'
+ -l, --no-hardlinks copy files instead of hard linking
Added: trunk/contrib/bin/copy-latest-pkgs.py
===================================================================
--- trunk/contrib/bin/copy-latest-pkgs.py 2011-01-11 16:27:02 UTC (rev 504)
+++ trunk/contrib/bin/copy-latest-pkgs.py 2011-01-11 17:20:02 UTC (rev 505)
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# Copyright (C) 2011 by Intevation GmbH
+# Authors:
+# Sascha L. Teichmann <sascha.teichmann at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+import os
+import re
+import sys
+import subprocess
+import logging
+import traceback
+
+from optparse import OptionParser
+from shutil import copyfile
+
+log = logging.getLogger(__name__)
+log.setLevel(logging.WARNING)
+log.addHandler(logging.StreamHandler(sys.stderr))
+
+SAEGEWERKER = "saegewerker"
+
+FIELD = re.compile("([a-zA-Z]+):\s*(.+)")
+
+
+class DebCmp(object):
+ """Helper class to make deb files comparable
+ by there versions.
+ """
+
+ def __init__(self, version, path):
+ self.version = version
+ self.path = path
+
+ def __cmp__(self, other):
+ if self.version == other.version:
+ return 0
+ if (subprocess.call([
+ "dpkg", "--compare-versions",
+ self.version, "gt", other.version]) == 0):
+ return +1
+ if (subprocess.call([
+ "dpkg", "--compare-versions",
+ self.version, "lt", other.version]) == 0):
+ return -1
+ return 0
+
+ def __str__(self):
+ return "version: %s / path: %s" % (
+ self.version,
+ self.path)
+
+def deb_info(deb, fields=["Package", "Version"]):
+ """Extract some meta info from a deb file."""
+ po = subprocess.Popen(
+ ["dpkg-deb", "-f", deb] + fields,
+ stdout=subprocess.PIPE)
+ out = po.communicate()[0]
+ return dict([m.groups()
+ for m in map(FIELD.match, out.splitlines()) if m])
+
+
+def copy_pkgs(src, dst, options):
+
+ archs = {}
+
+ for arch in os.listdir(src):
+ if arch == 'source': continue
+ arch_dir = os.path.join(src, arch)
+ if not os.path.isdir(arch_dir): continue
+ log.debug("found arch: '%s'" % arch)
+
+ tracks = {}
+
+ for track in os.listdir(arch_dir):
+ track_dir = os.path.join(arch_dir, track)
+ if not os.path.isdir(track_dir): continue
+
+ packages = {}
+
+ log.debug("track dir: '%s'" % track_dir)
+ for f in os.listdir(track_dir):
+ if not f.endswith(".deb"): continue
+ deb_path = os.path.join(track_dir, f)
+ if not os.path.isfile(deb_path): continue
+
+ info = deb_info(deb_path)
+ deb_cmp = DebCmp(info['Version'], deb_path)
+
+ packages.setdefault(info['Package'], []).append(deb_cmp)
+
+ tracks[track] =[max(debs) for debs in packages.itervalues()]
+
+ archs[arch] = tracks
+
+ copy = options.no_hardlinks and copyfile or os.link
+ action = options.no_hardlinks and "copy" or "link"
+
+ for arch, tracks in archs.iteritems():
+ log.debug("writing arch '%s'" % arch)
+ for track, debs in tracks.iteritems():
+ log.debug(" writing track '%s'" % track)
+ dst_dir = os.path.join(dst, arch, track)
+ if not os.path.exists(dst_dir):
+ try:
+ os.makedirs(dst_dir)
+ except:
+ log.warn(traceback.format_exc())
+ continue
+
+ for deb in debs:
+ src_path = deb.path
+ dst_path = os.path.join(dst_dir, os.path.basename(src_path))
+ log.info(" %s '%s' -> '%s'" % (action, src_path, dst_path))
+ if os.path.isfile(dst_path):
+ try: os.remove(dst_path)
+ except: log.warn(traceback.format_exc()); continue
+ try: copy(src_path, dst_path)
+ except: log.warn(traceback.format_exc())
+
+
+def main():
+ usage = "usage: %prog [options] src-dir dst-dir"
+ parser = OptionParser(usage=usage)
+ parser.add_option(
+ "-v", "--verbose", action="store_true",
+ dest="verbose",
+ help="verbose output")
+ parser.add_option(
+ "-d", "--dry-run", action="store_true",
+ dest="dry_run", default=False,
+ help="don't copy the deb files")
+ parser.add_option(
+ "-n", "--no-saegewerker", action="store_true",
+ dest="no_saegewerker", default=False,
+ help="Don't force run as '%s'" % SAEGEWERKER)
+ parser.add_option(
+ "-l", "--no-hardlinks", action="store_false",
+ dest="no_hardlinks", default=False,
+ help="copy files instead of hard linking")
+
+ options, args = parser.parse_args()
+
+ if len(args) < 2:
+ log.error("need at least two arguments")
+ sys.exit(1)
+
+ src, dst = args[0], args[1]
+
+ for d in (src, dst):
+ if not os.path.isdir(d):
+ log.error("'%s' is not a directory." % d)
+ sys.exit(1)
+
+ if options.verbose: log.setLevel(logging.INFO)
+
+ if not options.no_saegewerker and os.environ['USER'] != SAEGEWERKER:
+ log.error("Need to run as '%s'" % SAEGEWERKER)
+ sys.exit(1)
+
+ copy_pkgs(src, dst, options)
+
+if __name__ == '__main__':
+ main()
Property changes on: trunk/contrib/bin/copy-latest-pkgs.py
___________________________________________________________________
Name: svn:executable
+ *
More information about the Treepkg-commits
mailing list