changeset 271:12facd1b5f19

Implement tag detection for the KDEPIM enterprise 3.5 packages. This is a simple port of the implementation for the enterprise 4 branch. This change leads to a lot of duplicated code that needs to be refactored.
author Bernhard Herzog <bh@intevation.de>
date Thu, 07 May 2009 13:51:21 +0000
parents e5e23c3acaea
children 026dd7286431
files recipes/kde_enterprise_3_5/base.py recipes/kde_enterprise_3_5/kde_i18n.py recipes/kde_enterprise_3_5/kdepim.py
diffstat 3 files changed, 171 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/recipes/kde_enterprise_3_5/base.py	Thu May 07 13:51:21 2009 +0000
@@ -0,0 +1,161 @@
+# Copyright (C) 2007, 2008, 2009 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""Base classes for all kdepim packagers"""
+
+import os
+import time
+import inspect
+import re
+import logging
+
+import treepkg.packager
+import treepkg.subversion
+
+class TagDetector(object):
+
+    """Class to automatically find SVN tags and help package them
+
+    The tags are found using three parameters:
+      url -- The base url of the SVN tags directory to use
+      pattern -- A regular expression matching the subdirectories to
+                 consider in the tag directory specified by the url
+      subdir -- A subdirectory of the directory matched by pattern to
+                export and use to determine revision number
+
+    The subdir parameter is there to cope with the kdepim enterprise
+    tags.  The URL for a tag is of the form
+    .../tags/kdepim/enterprise4.0.<date>.<rev> .  Each such tag has
+    subdirectories for kdepim, kdelibs, etc.  The url and pattern are
+    used to match the URL for the tag, and the subdir is used to select
+    which part of the tag is meant.
+
+    The subdir also determines which SVN directory's revision number is
+    used.  Normally, just appending the subdir to the tag URL would be
+    enough for this, but the situation is more complex for
+    kdebase_workspace and kdebase_runtime, whose code comes from
+    different subdirectories of the kdebase-4.X-branch subdirectory (for
+    enterprise4 tags).  Here the revision number must be taken from
+    kdebase-4.X-branch, but the URL to use when exporting the sources,
+    must refer to e.g. kdebase-4.1-branch/kdebase_workspace.  To achieve
+    that, subdir may contain slashes to indicate subdirectories of
+    subdirectories, but only the first part of subdir (up to the first
+    slash) is used when determining the revision number.
+    """
+
+    def __init__(self, url, pattern, subdir):
+        self.url = url
+        self.pattern = re.compile(pattern)
+        self.subdir = subdir
+
+    def list_tags(self):
+        matches = []
+        if self.url:
+            for tag in treepkg.subversion.list_url(self.url):
+                if self.pattern.match(tag.rstrip("/")):
+                    matches.append(tag)
+        return sorted(matches)
+
+    def newest_tag_revision(self):
+        """Determines the newest tag revision and returns (tagurl, revno)
+        If no tag can be found, the method returns the tuple (None, None).
+        """
+        candidates = self.list_tags()
+        urlrev = (None, None)
+        if candidates:
+            newest = candidates[-1]
+            urlrev = self.determine_revision(self.url + "/" + newest,
+                                             self.subdir)
+        return urlrev
+
+    def determine_revision(self, baseurl, subdir):
+        urlrev = (None, None)
+        revision_url = baseurl + "/" + subdir.split("/")[0]
+        try:
+            revision = treepkg.subversion.last_changed_revision(revision_url)
+            urlrev = (baseurl + "/" + subdir, revision)
+        except treepkg.subversion.SubversionError:
+            pass
+        return urlrev
+
+
+class BaseSourcePackager(treepkg.packager.SourcePackager):
+
+    changemsg_template = None
+
+    def __init__(self, *args, **kw):
+        super(BaseSourcePackager, self).__init__(*args, **kw)
+        self.enterprise_version = (time.strftime("%Y%m%d", time.localtime()) \
+                                   + "." + str(self.revision))
+
+    def determine_package_version(self, directory):
+        enterprise_version = self.enterprise_version
+        return self.track.version_template % locals()
+
+    def do_package(self):
+        pkgbaseversion, pkgbasedir = self.export_sources()
+        self.update_version_numbers(pkgbasedir)
+
+        pkgbasename = self.pkg_basename + "_" + pkgbaseversion
+        origtargz = os.path.join(self.work_dir,
+                                 pkgbasename + ".orig.tar.gz")
+        self.create_tarball(origtargz, self.work_dir,
+                            os.path.basename(pkgbasedir))
+
+        changemsg = self.changemsg_template % dict(revision=self.revision)
+        self.copy_debian_directory(pkgbasedir, pkgbaseversion,
+                                   changemsg)
+
+        self.create_source_package(pkgbasedir, origtargz)
+        self.move_source_package(pkgbasename)
+
+
+class BasePackageTrack(treepkg.packager.PackageTrack):
+
+    extra_config_desc = [("version_template", str, "%(enterprise_version)s"),
+                         ("tags_url", str, ""),
+                         ("tags_pattern", str, ""),
+                         ("tags_subdir", str, "")]
+
+    def __init__(self, *args, **kw):
+        self.version_template = kw.pop("version_template")
+        tags_url = kw.pop("tags_url")
+        tags_pattern = kw.pop("tags_pattern")
+        tags_subdir = kw.pop("tags_subdir")
+        super(BasePackageTrack, self).__init__(*args, **kw)
+        self.tag_detector = TagDetector(tags_url, tags_pattern, tags_subdir)
+
+    def packager_for_new_revision(self):
+        logging.info("Checking tags")
+        self.tag_url = None
+        tag_url, tag_revision = self.tag_detector.newest_tag_revision()
+        logging.info("Found: %s: %s", tag_url, tag_revision)
+        if tag_url is not None:
+            revision = (tag_revision,
+                        self.rules_working_copy.last_changed_revision())
+            logging.info("New revision is %s", revision)
+            if revision not in self.get_revision_numbers():
+                logging.info("Revision %s has not been packaged yet",
+                             revision)
+                self.tag_url = tag_url
+                return self.revision_packager_cls(self, tag=tag_url, *revision)
+            else:
+                logging.info("Revision %s has already been packaged.",
+                             revision)
+
+        return super(BasePackageTrack, self).packager_for_new_revision()
+
+    def export_sources(self, to_dir):
+        if self.tag_url is not None:
+            self.export_tag(self.tag_url, to_dir)
+        else:
+            super(BasePackageTrack, self).export_sources(to_dir)
+
+    def export_tag(self, tag_url, to_dir):
+        logging.info("Exporting sources from %s to %r",
+                     tag_url, to_dir)
+        treepkg.subversion.export(tag_url, to_dir)
--- a/recipes/kde_enterprise_3_5/kde_i18n.py	Wed May 06 14:00:51 2009 +0000
+++ b/recipes/kde_enterprise_3_5/kde_i18n.py	Thu May 07 13:51:21 2009 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2008 by Intevation GmbH
+# Copyright (C) 2007, 2008, 2009 by Intevation GmbH
 # Authors:
 # Bernhard Herzog <bh@intevation.de>
 #
@@ -15,6 +15,7 @@
 import treepkg.run as run
 from treepkg.cmdexpand import cmdexpand
 
+import base
 
 class SourcePackager(treepkg.packager.SourcePackager):
 
@@ -125,13 +126,14 @@
     source_packager_cls = SourcePackager
 
 
-class PackageTrack(treepkg.packager.PackageTrack):
+class PackageTrack(base.BasePackageTrack):
 
     revision_packager_cls = RevisionPackager
 
     svn_external_subdirs = ["scripts", "scripts/admin", "documentation/kdepim"]
 
-    extra_config_desc = ["orig_tarball"]
+    extra_config_desc = base.BasePackageTrack.extra_config_desc \
+                        + ["orig_tarball"]
 
     def __init__(self, *args, **kw):
         self.orig_tarball = kw.pop("orig_tarball")
--- a/recipes/kde_enterprise_3_5/kdepim.py	Wed May 06 14:00:51 2009 +0000
+++ b/recipes/kde_enterprise_3_5/kdepim.py	Thu May 07 13:51:21 2009 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, 2008 by Intevation GmbH
+# Copyright (C) 2007, 2008, 2009 by Intevation GmbH
 # Authors:
 # Bernhard Herzog <bh@intevation.de>
 #
@@ -15,15 +15,12 @@
 import treepkg.util
 import treepkg.packager
 
+import base
 
-class SourcePackager(treepkg.packager.SourcePackager):
+class SourcePackager(base.BaseSourcePackager):
 
     pkg_basename = "kdepim"
-
-    def __init__(self, *args, **kw):
-        super(SourcePackager, self).__init__(*args, **kw)
-        self.enterprise_version = (time.strftime("%Y%m%d", time.localtime()) \
-                                   + "." + str(self.revision))
+    changemsg_template = "Update to SVN enterprise35 branch rev. %(revision)d"
 
     def kdepim_version(self, directory):
         """Determine the kdepim version.
@@ -55,31 +52,13 @@
             raise RuntimeError("kdepim: failed to update version numbers in %s"
                                % (", ".join(failed),))
 
-    def do_package(self):
-        pkgbaseversion, pkgbasedir = self.export_sources()
-        self.update_version_numbers(pkgbasedir)
-
-        pkgbasename = "kdepim_" + pkgbaseversion
-        origtargz = os.path.join(self.work_dir,
-                                 pkgbasename + ".orig.tar.gz")
-        self.create_tarball(origtargz, self.work_dir,
-                            os.path.basename(pkgbasedir))
-
-        changemsg = ("Update to SVN enterprise35 branch rev. %d"
-                     % (self.revision,))
-        self.copy_debian_directory(pkgbasedir, pkgbaseversion,
-                                   changemsg)
-
-        self.create_source_package(pkgbasedir, origtargz)
-        self.move_source_package(pkgbasename)
-
 
 class RevisionPackager(treepkg.packager.RevisionPackager):
 
     source_packager_cls = SourcePackager
 
 
-class PackageTrack(treepkg.packager.PackageTrack):
+class PackageTrack(base.BasePackageTrack):
 
     revision_packager_cls = RevisionPackager
 
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)