buildpackage{,-rpm}: add preexport hook
authorLuca Boccassi <bluca@debian.org>
Mon, 25 Jun 2018 22:37:02 +0000 (23:37 +0100)
committerGuido Günther <agx@sigxcpu.org>
Sun, 28 Oct 2018 11:30:25 +0000 (12:30 +0100)
Sometimes it is necessary to perform operations before preparing the
tarballs and exporting to the build directory.
One such case is when having to handle extremely large binary assets in
the orig tarball and at the same time complex packaging code, which
makes it desirable to separate the two into different repositories for
easier handling.
A pre-export hook allows to ensure that the tarball repository is
present and checked out at the correct branch.

Closes: #909266
Signed-off-by: Luca Boccassi <bluca@debian.org>
debian/gbp.completion
docs/chapters/building.xml
docs/manpages/gbp-buildpackage-rpm.xml
docs/manpages/gbp-buildpackage.xml
gbp/config.py
gbp/scripts/buildpackage.py
gbp/scripts/buildpackage_rpm.py
tests/component/deb/test_buildpackage.py
tests/component/rpm/test_buildpackage_rpm.py

index 706cfdf73f78c69c952cd93c07167263d74a813e..37e85eaaf67fab10b7ea7d7915a731e001f26466 100644 (file)
@@ -55,7 +55,7 @@ _gbp_comp ()
     local remote_config_opts="--remote-config\="
     local file_opts="--postimport\= --git-builder\= --git-cleaner\= \
                      --git-export-dir\= --git-postbuild\= --git-postexport\= \
-                     --git-posttag\= --git-prebuild\= --git-tarball-dir\= \
+                     --git-posttag\= --git-prebuild\= --git-preexport\= --git-tarball-dir\= \
                      --posttag\= --tarball-dir\="
     local start_opt=""
 
index 1fbd5ae3c301422365f1a4190606c53cdbdf8b06..af1fe318419aed877f5f2c15e3a1da8da3585b14 100644 (file)
@@ -266,6 +266,18 @@ rm -f rules.* control.*
 
 exit 0
 </programlisting>
+    </sect2>
+    <sect2 id="gbp.building.preexport">
+    <title>Running preexport hook</title>
+    <para>&gbp-buildpackage; exports several variables into the
+       <option>preexport</option>'s environment (for details see
+       the <xref linkend="man.gbp.buildpackage"/> manual page). The motivation
+       for the preexport action is to allow further actions before preparing and
+       exporting the orig tarballs to the build directory.
+       A usecase could be having the orig tarballs in a separate repository due to
+       very large binary assets, that need to be checked out to the correct branch
+       before creating the tarballs.
+    </para>
     </sect2>
     </sect1>
 </chapter>
index 9f8f438184b7a3986490cacf7b390173c49e2587..18a0a1e18c6dffb27e12b8790cd55488ad012683 100644 (file)
@@ -39,6 +39,7 @@
       <arg><option>--git-postbuild=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-postexport=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-prebuild=</option><replaceable>COMMAND</replaceable></arg>
+      <arg><option>--git-preexport=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-[no-]build</option></arg>
       <arg><option>--git-[no-]hooks</option></arg>
       <arg><option>--git-packaging-tag=</option><replaceable>TAG-FORMAT</replaceable></arg>
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><option>--git-preexport=</option><replaceable>COMMAND</replaceable>
+        </term>
+        <listitem>
+          <para>
+          Execute <replaceable>COMMAND</replaceable> before exporting the source
+          tree.
+          </para>
+          <para>
+          Exported environment variables are: <envar>GBP_GIT_DIR</envar> (the
+          repository the package is being built from),
+          <envar>GBP_BUILD_DIR</envar> (the build dir).
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><option>--git-postexport=</option><replaceable>COMMAND</replaceable>
         </term>
         </term>
         <listitem>
           <para>
-          Enable running all (cleaner, postexport, prebuild, postbuild, and
+          Enable running all (cleaner, preexport, postexport, prebuild, postbuild, and
           posttag) hooks. Note: the <option>--git-builder</option> command is
           not affected by this option.
           </para>
index 9b6bcce39aa3264f56b5373d46a74c69c1d05569..d25f5c8993789ad2869cad3330cef50eacebb92c 100644 (file)
@@ -39,6 +39,7 @@
       <arg><option>--git-pbuilder-options</option>=<replaceable>PBUILDER_OPTIONS</replaceable></arg>
       <arg><option>--git-[no-]sign-tags</option></arg>
       <arg><option>--git-keyid=</option><replaceable>GPG-KEYID</replaceable></arg>
+      <arg><option>--git-preexport=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-postexport=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-prebuild=</option><replaceable>COMMAND</replaceable></arg>
       <arg><option>--git-postbuild=</option><replaceable>COMMAND</replaceable></arg>
        build. These options configure what will be run:
       </para>
       <variablelist>
+       <varlistentry>
+          <term><option>--git-preexport=</option><replaceable>COMMAND</replaceable>
+          </term>
+          <listitem>
+            <para>
+              Execute <replaceable>COMMAND</replaceable> before exporting the source
+              tree. Valid only if --git-export-dir has been specified.
+            </para>
+            <para>
+              Exported environment variables are: <envar>GBP_GIT_DIR</envar> (the
+              repository the package is being built from),
+              <envar>GBP_BUILD_DIR</envar> (the build dir).
+            </para>
+          </listitem>
+       </varlistentry>
        <varlistentry>
           <term><option>--git-postexport=</option><replaceable>COMMAND</replaceable>
           </term>
           </term>
           <listitem>
             <para>
-              Enable running all (cleaner, postexport, prebuild, postbuild, and
+              Enable running all (cleaner, preexport, postexport, prebuild, postbuild, and
               posttag) hooks. Note: the <option>--git-builder</option> command is
               not affected by this option.
             </para>
index 76a850de46ef048bf1bd0aa17199c0ed90baea60..504118024b3a9643d971bc351e858d0d1741a128 100644 (file)
@@ -163,6 +163,7 @@ class GbpOptionParser(OptionParser):
                 'posttag': '',
                 'pq-from': 'DEBIAN',
                 'prebuild': '',
+                'preexport': '',
                 'pristine-tar': 'False',
                 'pristine-tar-commit': 'False',
                 'purge': 'True',
index d345b4687817e24219cf493ed4284044bd973d6d..d3a3222e1e0caab668c1bf46f4f259808a02e0ec 100755 (executable)
@@ -277,7 +277,7 @@ def mangle_export_wc_opts(options):
 
 def disable_hooks(options):
     """Disable all hooks (except for builder)"""
-    for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']:
+    for hook in ['cleaner', 'preexport', 'postexport', 'prebuild', 'postbuild', 'posttag']:
         if getattr(options, hook):
             gbp.log.info("Disabling '%s' hook" % hook)
             setattr(options, hook, '')
@@ -406,6 +406,9 @@ def build_parser(name, prefix=None):
     cmd_group.add_config_file_option(option_name="prebuild", dest="prebuild",
                                      help="hook to run before a build, "
                                           "default is '%(prebuild)s'")
+    cmd_group.add_config_file_option(option_name="preexport", dest="preexport",
+                                     help="hook to run before exporting the source tree, "
+                                          "default is '%(preexport)s'")
     cmd_group.add_config_file_option(option_name="postexport", dest="postexport",
                                      help="hook to run after exporting the source tree, "
                                           "default is '%(postexport)s'")
@@ -505,6 +508,14 @@ def main(argv):
             build_dir = export_dir if options.export_dir else repo.path
             changes_file = changes_file_name(source, build_dir, options.builder, dpkg_args)
 
+            # Run preexport hook
+            if options.export_dir and options.preexport:
+                Hook('Preexport', options.preexport,
+                     extra_env=Hook.md(hook_env,
+                                       {'GBP_GIT_DIR': repo.git_dir,
+                                        'GBP_BUILD_DIR': build_dir})
+                     )()
+
             # Get/build the upstream tarball if necessary. We delay this in
             # case of a postexport hook so the hook gets a chance to modify the
             # sources and create different tarballs (#640382)
index 16b5eb56cf3490a6e5db7be52a86c21815bebcf0..952ff2479321e6337f6ad9a52b054f18674d02cb 100644 (file)
@@ -296,7 +296,7 @@ def create_packaging_tag(repo, commit, name, version, options):
 
 def disable_hooks(options):
     """Disable all hooks (except for builder)"""
-    for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']:
+    for hook in ['cleaner', 'preexport', 'postexport', 'prebuild', 'postbuild', 'posttag']:
         if getattr(options, hook):
             gbp.log.info("Disabling '%s' hook" % hook)
             setattr(options, hook, '')
@@ -395,6 +395,10 @@ def build_parser(name, prefix=None, git_treeish=None):
     cmd_group.add_config_file_option(option_name="prebuild", dest="prebuild",
                                      help="command to run before a build, default is "
                                      "'%(prebuild)s'")
+    cmd_group.add_config_file_option(option_name="preexport",
+                                     dest="preexport",
+                                     help="command to run before exporting the source tree, "
+                                     "default is '%(preexport)s'")
     cmd_group.add_config_file_option(option_name="postexport",
                                      dest="postexport",
                                      help="command to run after exporting the source tree, "
@@ -532,6 +536,13 @@ def main(argv):
                                  options.export_sourcedir))
             spec_dir = makedir(os.path.join(export_dir, options.export_specdir))
 
+            # Run preexport hook
+            if options.preexport:
+                RunAtCommand(options.preexport, shell=True,
+                             extra_env={'GBP_GIT_DIR': repo.git_dir,
+                                        'GBP_BUILD_DIR': export_dir}
+                             )()
+
             # Move packaging files to final export dir
             gbp.log.debug("Exporting packaging files from '%s' to '%s'" %
                           (dump_dir, export_dir))
index 7aa8577ffc5e77f9bdfbdde916dec5144fdd7842..c8a31e77744b9767b95939250cde267586d730ae 100644 (file)
@@ -303,3 +303,12 @@ class TestBuildpackage(ComponentTestBase):
                             '--git-tarball-dir=../tarballs'])
         eq_(ret, 1)
         self._check_log(-1, "gbp:error: Non-native package 'hello-debhelper' has invalid version '3.0'")
+
+    @RepoFixtures.quilt30()
+    def test_preexport(self, repo):
+        """Test the pre-export hook """
+        preexport_out = os.path.join(repo.path, '..', 'preexport.out')
+        self._test_buildpackage(repo, ['--git-export-dir=../export-dir',
+                                       '--git-preexport=printenv > %s' % preexport_out])
+        ok_(os.path.exists(preexport_out))
+        self.check_hook_vars('../preexport', ["GBP_BUILD_DIR", "GBP_GIT_DIR"])
index 78e9ff3759f9340b4af0be286a040bc45137f9e7..51c76cb1229db7307f63b3f853336b4dd409526d 100644 (file)
@@ -467,11 +467,13 @@ class TestGbpRpm(RpmRepoTestBase):
         self.init_test_repo('gbp-test-native')
 
         cleaner = 'echo -n cleaner >> ../hooks'
+        preexport = 'echo -n preexport >> $GBP_TMP_DIR/../hooks'
         postexport = 'echo -n postexport >> $GBP_TMP_DIR/../hooks'
         prebuild = 'echo -n prebuild >> $GBP_BUILD_DIR/../hooks'
         postbuild = 'echo -n postbuild >> $GBP_BUILD_DIR/../hooks'
         posttag = 'echo -n posttag >> ../hooks'
         args = ['--git-cleaner=%s' % cleaner,
+                '--git-preexport=%s' % preexport,
                 '--git-postexport=%s' % postexport,
                 '--git-prebuild=%s' % prebuild,
                 '--git-postbuild=%s' % postbuild,
@@ -483,13 +485,13 @@ class TestGbpRpm(RpmRepoTestBase):
 
         # Export and build scripts are run when not tagging
         eq_(mock_gbp(args), 0)
-        self.check_and_rm_file('../hooks', 'cleanerpostexportprebuildpostbuild')
+        self.check_and_rm_file('../hooks', 'cleanerpreexportpostexportprebuildpostbuild')
         shutil.rmtree('../rpmbuild')
 
         # All hooks are run when building
         eq_(mock_gbp(args + ['--git-tag', '--git-packaging-tag=tag2']), 0)
         self.check_and_rm_file('../hooks',
-                               'cleanerpostexportprebuildpostbuildposttag')
+                               'cleanerpreexportpostexportprebuildpostbuildposttag')
         shutil.rmtree('../rpmbuild')
 
         # Run with hooks disabled