view treepkg/subversion.py @ 228:d2ddd037ddaf

Fix a bug introduced by the subversion interface reorganization
author Bernhard Herzog <bh@intevation.de>
date Fri, 09 Jan 2009 21:13:51 +0000
parents 6bac65dcf258
children e387b879fd38
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.

"""Collection of subversion utility code"""

import os

import run
from cmdexpand import cmdexpand
from util import extract_value_for_key


def checkout(url, localdir, revision=None, recurse=True):
    """Runs svn to checkout the repository at url into the localdir"""
    args = []
    if revision:
        args.extend(["--revision", revision])
    if not recurse:
        args.append("-N")
    run.call(cmdexpand("svn checkout -q @args $url $localdir", **locals()))

def update(localdir, revision=None, recurse=True):
    """Runs svn update on the localdir.
    The parameter revision, if given, is passed to svn as the value of
    the --revision option.
    """
    args = []
    if revision:
        args.extend(["--revision", revision])
    if not recurse:
        args.append("-N")
    run.call(cmdexpand("svn update -q @args $localdir", **locals()))

def export(src, dest):
    """Runs svn export src dest"""
    run.call(cmdexpand("svn export -q $src $dest", **locals()))

def last_changed_revision(svn_working_copy):
    """return the last changed revision of an SVN working copy as an int"""
    # Make sure we run svn under the C locale to avoid localized
    # messages
    env = os.environ.copy()
    env["LANG"] = "C"

    output = run.capture_output(cmdexpand("svn info $svn_working_copy",
                                          **locals()),
                                env=env)
    return int(extract_value_for_key(output.splitlines(),
                                     "Last Changed Rev:"))


class SvnRepository(object):

    """Describes a subversion repository"""

    def __init__(self, url, external_subdirs=()):
        """Initialize the subversion repository description
        Parameters:
          url -- The url of the repository
          external_subdirs -- A list of subdirectories which are managed
                              by svn externals definitions
        """
        self.url = url
        self.external_subdirs = external_subdirs

    def checkout(self, localdir, revision=None):
        """Checks out the repository into localdir.  The revision
        parameter should be an and indicates the revision to check out.
        """
        checkout(self.url, localdir, revision=revision)

    def export(self, localdir, destdir):
        """Exports the working copy in localdir to destdir"""
        export(localdir, destdir)
        for subdir in self.external_subdirs:
            absdir = os.path.join(destdir, subdir)
            if not os.path.isdir(absdir):
                export(os.path.join(localdir, subdir), absdir)

    def last_changed_revision(self, localdir):
        """Returns the last changed revision of the working copy in localdir"""
        return max([last_changed_revision(os.path.join(localdir, d))
                    for d in [localdir] + list(self.external_subdirs)])


class SvnWorkingCopy(object):

    """Represents a checkout of a subversion repository"""

    def __init__(self, repository, localdir, logger=None):
        """
        Initialize the working copy.
        Parameters:
          repository -- The SvnRepository instance describing the
                        repository
          localdir -- The directory for the working copy
          logger -- logging object to use for some info/debug messages
        """
        self.repository = repository
        self.localdir = localdir
        self.logger = logger

    def log_info(self, *args):
        if self.logger is not None:
            self.logger.info(*args)

    def update_or_checkout(self, revision=None):
        """Updates the working copy or creates by checking out the repository"""
        if os.path.exists(self.localdir):
            self.log_info("Updating the working copy in %r", self.localdir)
            update(self.localdir, revision=revision)
        else:
            self.log_info("The working copy in %r doesn't exist yet."
                          "  Checking out from %r",
                          self.localdir, self.repository.url)
            self.repository.checkout(self.localdir, revision=revision)

    def export(self, destdir):
        """Exports the working copy to destdir"""
        self.repository.export(self.localdir, destdir)

    def last_changed_revision(self):
        """Returns the last changed rev of the working copy"""
        return self.repository.last_changed_revision(self.localdir)
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)