view recipes/kde_enterprise_3_5/base.py @ 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
children 4b700b39c32f
line wrap: on
line source
# 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)
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)