changeset 304:6cffb43a28ca

Add a way to specify svn subset checkouts where only parts of a source tree are checked out. The subset can be specified in the configuration file on a per-track basis. This feature was already present for some of the kde enterprise packagers but is now part of the base classes.
author Bernhard Herzog <bh@intevation.de>
date Thu, 26 Nov 2009 20:20:57 +0000
parents df01eb4dbfc5
children 3781e9958eba
files test/test_readconfig.py treepkg/packager.py treepkg/readconfig.py treepkg/subversion.py
diffstat 4 files changed, 94 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/test/test_readconfig.py	Thu Nov 26 15:37:48 2009 +0000
+++ b/test/test_readconfig.py	Thu Nov 26 20:20:57 2009 +0000
@@ -46,6 +46,8 @@
 
 [pkg_extraargs]
 svn_url: svn://example.com/%(name)s/trunk
+svn_subset: -N .
+            subdir
 base_dir: %(tracks_dir)s/%(name)s
 packager_class: readconfig_test.extraargs
 orig_tarball: %(base_dir)s/mytarball.tgz
@@ -98,6 +100,7 @@
                  pkg_basename="",
                  root_cmd=['sudo'],
                  signing_key_id="",
+                 svn_subset=[(".", False), ("subdir", True)],
                  svn_url="svn://example.com/extraargs/trunk",
                  rules_svn_url="file:///tmp/my-debian-repository",
                  orig_tarball=("/home/builder/mill/"
@@ -117,4 +120,5 @@
                  pkg_basename="simple1",
                  root_cmd=['sudo'],
                  signing_key_id="abcd1234",
+                 svn_subset=[],
                  svn_url="svn://example.com/simple/trunk")])
--- a/treepkg/packager.py	Thu Nov 26 15:37:48 2009 +0000
+++ b/treepkg/packager.py	Thu Nov 26 20:20:57 2009 +0000
@@ -345,7 +345,8 @@
                  pkg_revision_template="treepkg%(pkg_revision)d",
                  handle_dependencies=False, signing_key_id="", do_build=True,
                  rules_svn_url=None, deb_build_options="", pkg_basename="",
-                 changelog_msg_template="Update to r%(revision)s"):
+                 changelog_msg_template="Update to r%(revision)s",
+                 svn_subset=()):
         self.name = name
         if not pkg_basename:
             pkg_basename = name
@@ -365,7 +366,8 @@
         self.pkg_dir_template = "%(revision)d-%(rules_revision)d"
         self.pkg_dir_regex = re.compile(r"(?P<revision>[0-9]+)"
                                         r"-(?P<rules_revision>[0-9]+)$")
-        repo = SvnRepository(svn_url, self.svn_external_subdirs)
+        repo = SvnRepository(svn_url, self.svn_external_subdirs,
+                             subset=svn_subset)
         self.working_copy = SvnWorkingCopy(repo, self.checkout_dir,
                                            logger=logging)
         if rules_svn_url:
--- a/treepkg/readconfig.py	Thu Nov 26 15:37:48 2009 +0000
+++ b/treepkg/readconfig.py	Thu Nov 26 20:20:57 2009 +0000
@@ -23,8 +23,50 @@
     raise ValueError("cannot determine boolean value of %r" % (s,))
 
 
+def convert_subversion_subset(raw):
+    """Converts the string representation an svn subset into internal form
+    The format in the config file is typically:
+    svn_url: svn://example.com/repository/trunk
+    svn_subset: -N .
+                subdir1
+                subdir2
+
+    Each line of the svn_subset value consists of an optional flag
+    followed by a subdirectory.  Empty lines are ignored.  Each
+    non-empty line is split into words using shlex.split, so whitespace
+    characters can be included in filenames using e.g. quotes (see the
+    shlex documentation for details).  The only flag supported is -N
+    which indicates that the subdirectory on that line is not to be
+    checked out recursively.  If -N is given on a line, svn checkout
+    will be called with -N as parameter.
+
+    The example above will be converted into the internal form [('.',
+    False), ('subdir1', True), ('subdir2', True)] used by the
+    treepkg.subversion module.
+    """
+    subset = []
+    for line in raw.splitlines():
+        split = shlex.split(line)
+        if len(split) < 1:
+            # ignore empty lines
+            continue
+        subdir = split[-1]
+        recurse = True
+        flags = split[:-1]
+        if flags:
+            if flags == ["-N"]:
+                recurse = False
+            else:
+                raise ValueError("Only -N is supported as flag, but flags = %r"
+                                 % (flags,))
+        subset.append((subdir, recurse))
+    return subset
+
+
 packager_desc = [
-    "name", "base_dir", "svn_url", ("rules_svn_url", str, ""), "packager_class",
+    "name", "base_dir",
+    "svn_url", ("svn_subset", convert_subversion_subset, ""),
+    ("rules_svn_url", str, ""), "packager_class",
     ("root_cmd", shlex.split, "sudo"), "pbuilderrc",
     "deb_email", "deb_fullname", ("deb_build_options", str, ""),
     "pkg_revision_template", ("pkg_basename", str, ""),
--- a/treepkg/subversion.py	Thu Nov 26 15:37:48 2009 +0000
+++ b/treepkg/subversion.py	Thu Nov 26 20:20:57 2009 +0000
@@ -120,21 +120,60 @@
 
     """Describes a subversion repository"""
 
-    def __init__(self, url, external_subdirs=()):
+    def __init__(self, url, external_subdirs=(), subset=()):
         """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
+
+          subset -- A sequence of (filename, recurse) pairs where
+                    filename is a filename (usually a directory name)
+                    relative to url and recurse should be a boolean
+                    indicating whether checkout filename with recursion.
+                    If recurse is False, svn checkout/export will be
+                    called with the -N option.
+
+                    The first item in subset should be for '.', which
+                    indicates the top-level directory under url.  If a
+                    non-empty subset is given this will usually be
+                    ('.', False) so that the top-level directory is not
+                    checked out recursively.
         """
         self.url = url
         self.external_subdirs = external_subdirs
+        if not subset:
+            # default subset is to checkout the top-level directory at
+            # URL recursively.  Alwas having a subset makes the code
+            # simpler
+            subset = [(".", True)]
+        self.subset = subset
 
     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.
+        """Checks out the repository into localdir.
+        The revision parameter should be an int and indicates the
+        revision to check out or it should be None to indicate that the
+        newest version is to be checked out.
         """
-        checkout(self.url, localdir, revision=revision)
+        base_url = self.url
+        if not base_url.endswith("/"):
+            base_url += "/"
+        subdir, recurse = self.subset[0]
+        checkout(base_url + subdir, os.path.join(localdir, subdir),
+                 revision=revision, recurse=recurse)
+        for subdir, recurse in self.subset[1:]:
+            update(os.path.join(localdir, subdir), revision=revision,
+                   recurse=recurse)
+        if len(self.subset) > 1 and revision is None:
+            # do an additional update on the whole working copy after
+            # creating a subset checkout so that svn info will show
+            # revision numbers that match the entire working copy
+            # (externals are handled elsewhere).  The repository might
+            # have been changed between the initial checkout of the
+            # top-level directory and the updates for the
+            # subdirectories.
+            update(localdir, revision=revision)
 
     def export(self, localdir, destdir):
         """Exports the working copy in localdir to destdir"""
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)