git-buildpackage: special case non-submodule tarfile generation
authorGuido Günther <agx@sigxcpu.org>
Mon, 21 Mar 2011 13:20:21 +0000 (14:20 +0100)
committerGuido Günther <agx@sigxcpu.org>
Mon, 21 Mar 2011 20:05:34 +0000 (21:05 +0100)
Tarfile generation with submodules is slower since we need to
concatenate several tarfiles and compress afterwards. So special case
the common non submodule case and add a testcase to check the tarfiles
content.

git-buildpackage
tests/04_test_gbp_submodules.py

index fa7abe7..26d18fa 100755 (executable)
@@ -45,58 +45,85 @@ wc_name = "WC"
 wc_index = ".git/gbp_index"
 
 
-def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level):
-    "create a compressed orig tarball in output_dir using git_archive"
+def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, comp_opts):
+    """
+    Create tar.gz of an archive with submodules
 
-    try:
-        comp_opts = du.compressor_opts[comp_type][0]
-    except KeyError:
-        raise GbpError, "Unsupported compression type '%s'" % comp_type
+    since git-archive always writes an end of tarfile trailer we concatenate
+    the generated archives using tar and compress the result.
 
-    output = os.path.join(output_dir, du.orig_file(cp, comp_type))
-    prefix = "%s-%s" % (cp['Source'], cp['Upstream-Version'])
+    Exception handling is left to the caller.
+    """
 
-    # make space for main and submodule tarfiles
+    tarfile = output.rsplit('.', 1)[0]
     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)
+                     output=tarfile, treeish=treeish)
 
-        # generate and integrate each submodule's tarfile into main_tarfile
-        if repo.has_submodules():
-            repo.update_submodules()
+        # generate each submodule's tarfile and append it to the main archive
         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]))
 
+            gbp.log.debug("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)
+            CatenateTarArchive(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)
+        ret = os.system("%s -%s %s %s" % (comp_type, comp_level, comp_opts, tarfile))
         if ret:
             raise GbpError("Error creating %s: %d" % (output, ret))
+    finally:
+        shutil.rmtree(tempdir)
+
+
+def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, comp_opts):
+    """
+    Create tar.gz of an archive without submodules
+
+    Exception handling is left to the caller.
+    """
+    pipe = pipes.Template()
+    pipe.prepend("git archive --format=tar --prefix=%s/ %s" % (prefix, treeish), '.-')
+    pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts),  '--')
+    ret = pipe.copy('', output)
+    if ret:
+        raise GbpError("Error creating %s: %d" % (output, ret))
+
+
+def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level):
+    "create a compressed orig tarball in output_dir using git_archive"
+    try:
+        comp_opts = du.compressor_opts[comp_type][0]
+    except KeyError:
+        raise GbpError, "Unsupported compression type '%s'" % comp_type
+
+    output = os.path.join(output_dir, du.orig_file(cp, comp_type))
+    prefix = "%s-%s" % (cp['Source'], cp['Upstream-Version'])
+
+    try:
+        if repo.has_submodules():
+            repo.update_submodules()
+            git_archive_submodules(repo, treeish, output, prefix,
+                                   comp_type, comp_level, comp_opts)
+
+        else:
+            git_archive_single(repo, treeish, output, prefix,
+                               comp_type, comp_level, comp_opts)
     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 GbpError:
+        raise
     except Exception as e:
         gbp.log.err("Error creating %s: %s" % (output, e))
         return False
-    finally:
-        shutil.rmtree(tempdir)
     return True
 
 
index 160e5b5..5fb5c29 100644 (file)
@@ -2,6 +2,7 @@
 
 import os
 import shutil
+import tarfile
 import tempfile
 
 import gbp.git
@@ -107,4 +108,11 @@ def test_create_tarball():
                                         "bzip2",
                                         "9")
 
+def test_chacke_tarfile():
+    """Check the contents of the created tarfile"""
+    t = tarfile.open(os.path.join(tmpdir,"test_0.1.orig.tar.bz2"), 'r:*')
+    files = t.getmembers()
+    assert "test-0.1/.gitmodules" in [ f.name for f in files ]
+    assert len(files) == 6
+
 # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: