git-buildpackage: submodule support for git_archive
authorGuido Günther <agx@sigxcpu.org>
Fri, 18 Mar 2011 11:14:14 +0000 (12:14 +0100)
committerGuido Günther <agx@sigxcpu.org>
Fri, 18 Mar 2011 19:46:50 +0000 (20:46 +0100)
Heavily based on work by Sean Finney and Chow Loong Jin

Closes: #588752

git-buildpackage

index 1a8c222..d01ee39 100755 (executable)
@@ -24,10 +24,13 @@ import os, os.path
 import pipes
 import sys
 import time
+import tempfile
+import shutil
 import gbp.deb as du
 from gbp.git import (GitRepositoryError, GitRepository, build_tag)
-from gbp.command_wrappers import (GitTag, Command, RunAtCommand, CommandExecFailed,
-                                  PristineTar, RemoveTree, GitAdd)
+from gbp.command_wrappers import (GitTag, Command,
+                                  RunAtCommand, CommandExecFailed, PristineTar,
+                                  RemoveTree, GitAdd, CatenateTarArchive)
 from gbp.config import (GbpOptionParser, GbpOptionGroup)
 from gbp.errors import GbpError
 from glob import glob
@@ -41,24 +44,8 @@ wc_name = "WC"
 # index file name used to export working copy
 wc_index = ".git/gbp_index"
 
-def git_archive_pipe(prefix, pipe, output, treeish):
-    """run the git_archive pipe"""
-    pipe.prepend('git archive --format=tar --prefix=%s/ %s' % (prefix, treeish), '.-')
-    try:
-        ret = pipe.copy('', output)
-        if ret:
-            gbp.log.err("Error creating %s: %d" % (output, ret))
-            return False
-    except OSError, err:
-        gbp.log.err("Error creating %s: %s" % (output, err[0]))
-        return False
-    except:
-        gbp.log.err("Error creating %s" % (output,))
-        return False
-    return True
 
-
-def git_archive(cp, output_dir, treeish, comp_type, comp_level):
+def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level):
     "create a compressed orig tarball in output_dir using git_archive"
 
     try:
@@ -69,9 +56,48 @@ def git_archive(cp, output_dir, treeish, comp_type, comp_level):
     output = os.path.join(output_dir, du.orig_file(cp, comp_type))
     prefix = "%s-%s" % (cp['Source'], cp['Upstream-Version'])
 
-    pipe = pipes.Template()
-    pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts),  '--')
-    return git_archive_pipe(prefix, pipe, output, treeish)
+    # make space for main and submodule tarfiles
+    tempdir = tempfile.mkdtemp()
+    main_tarfile = os.path.join(tempdir, "main.tar")
+    submodule_tarfile = os.path.join(tempdir, "submodule.tar")
+
+    try:
+        # generate main tarfile
+        repo.archive(format='tar', prefix='%s/' % (prefix),
+                     output=main_tarfile, treeish=treeish)
+
+        # generate and integrate each submodule's tarfile into main_tarfile
+        if repo.has_submodules():
+            repo.update_submodule()
+        for (subdir, commit) in repo.get_submodules(treeish):
+            tarpath = [subdir, subdir[2:]][subdir.startswith("./")]
+            gbp.log.info("Processing submodule  %s (%s)" % (subdir, commit[0:8]))
+
+            repo.archive(format='tar', prefix='%s/%s/' % (prefix, tarpath),
+                         output=submodule_tarfile, treeish=commit, cwd=subdir)
+            CatenateTarArchive(main_tarfile)(submodule_tarfile)
+
+        # compress the output
+        pipe = pipes.Template()
+        pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts),  '--')
+        ret = pipe.copy(main_tarfile, output)
+        if ret:
+            raise GbpError("Error creating %s: %d" % (output, ret))
+    except CommandExecFailed:
+        gbp.log.err("Error generating submodules' archives")
+        return False
+    except GbpError, err:
+        gbp.log.err(err)
+        return False
+    except OSError, err:
+        gbp.log.err("Error creating %s: %s" % (output, err[0]))
+        return False
+    except Exception as e:
+        gbp.log.err("Error creating %s: %s" % (output, e))
+        return False
+    finally:
+        shutil.rmtree(tempdir)
+    return True
 
 
 def dump_tree(repo, export_dir, treeish):
@@ -170,7 +196,7 @@ def git_archive_build_orig(repo, cp, output_dir, options):
         raise GbpError # git-ls-tree printed an error message already
     gbp.log.debug("Building upstream tarball with compression '%s -%s'" % (options.comp_type,
                                                                            options.comp_level))
-    if not git_archive(cp, output_dir, upstream_tree,
+    if not git_archive(repo, cp, output_dir, upstream_tree,
                        options.comp_type, options.comp_level):
         raise GbpError, "Cannot create upstream tarball at '%s'" % output_dir