pq-rpm: add new --pq-branch option
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Fri, 11 May 2012 08:29:24 +0000 (11:29 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Mar 2015 08:07:46 +0000 (10:07 +0200)
Adds a new command line option '--pq-branch' to set the name of
patch-queue branches. Changes the defaults pq-branch name for rpm tools
to 'development/%(branch)s' (instead of the old
'patch-queue/%(branch)s').

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
gbp/config.py
gbp/scripts/pq_rpm.py
tests/component/rpm/test_pq_rpm.py

index 53680943e6a9c6eaf4e58865deb263a607b4edef..ae022a3b11948e28f4cdaa63ad25e16e65141886 100644 (file)
@@ -611,6 +611,7 @@ class GbpOptionParserRpm(GbpOptionParser):
             'packaging-tag'             : 'packaging/%(version)s',
             'packaging-tag-msg'         : '%(pkg)s %(vendor)s release '\
                                           '%(version)s',
+            'pq-branch'                 : 'development/%(branch)s',
             'spec-file'                 : '',
             'export-dir'                : '../rpmbuild',
             'native'                    : 'auto',
@@ -639,6 +640,9 @@ class GbpOptionParserRpm(GbpOptionParser):
             'packaging-tag-msg':
                   ("Format string for packaging tag messages, "
                    "default is '%(packaging-tag-msg)s'"),
+            'pq-branch':
+                "format string for the patch-queue branch name, default is "
+                "'%(pq-branch)s'",
             'spec-file':
                 "Spec file to use, causes the packaging-dir option to be "
                 "ignored, default is '%(spec-file)s'",
index c403c77f958f40c074e1c99f0fc32a00c85c8223..655b4b57eefaac412edd768c7769478b9450f238 100755 (executable)
@@ -40,8 +40,7 @@ from gbp.rpm import (SpecFile, NoSpecError, guess_spec, guess_spec_repo,
                      spec_from_repo)
 from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base,
             parse_gbp_commands, format_patch, format_diff,
-            switch_to_pq_branch, apply_single_patch, apply_and_commit_patch,
-            drop_pq, switch_pq)
+            apply_and_commit_patch, drop_pq)
 from gbp.scripts.common.buildpackage import dump_tree
 
 
@@ -315,7 +314,7 @@ def import_spec_patches(repo, options):
         base = current
     upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
     packager = get_packager(spec)
-    pq_branch = pq_branch_name(base, options)
+    pq_branch = pq_branch_name(base, options, spec.version)
 
     # Create pq-branch
     if repo.has_branch(pq_branch) and not options.force:
@@ -376,6 +375,57 @@ def rebase_pq(repo, options):
     GitCommand("rebase")([upstream_commit])
 
 
+def switch_pq(repo, options):
+    """Switch to patch-queue branch if on base branch and vice versa"""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        gbp.log.info("Switching to branch '%s'" % base)
+        repo.checkout(base)
+    else:
+        switch_to_pq_branch(repo, current, options)
+
+
+def drop_pq_rpm(repo, options):
+    """Remove pq branch"""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        spec = parse_spec(options, repo, base)
+    else:
+        spec = parse_spec(options, repo)
+    drop_pq(repo, current, options, spec.version)
+
+
+def switch_to_pq_branch(repo, branch, options):
+    """
+    Switch to patch-queue branch if not already there, create it if it
+    doesn't exist yet
+    """
+    if is_pq_branch(branch, options):
+        return
+
+    spec = parse_spec(options, repo, branch)
+    pq_branch = pq_branch_name(branch, options, spec.version)
+    if not repo.has_branch(pq_branch):
+        upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
+        try:
+            repo.create_branch(pq_branch, rev=upstream_commit)
+        except GitRepositoryError as err:
+            raise GbpError("Cannot create patch-queue branch: %s" % err)
+
+    gbp.log.info("Switching to branch '%s'" % pq_branch)
+    repo.set_branch(pq_branch)
+
+def apply_single_patch(repo, patchfile, options):
+    """Apply a single patch onto the pq branch"""
+    current = repo.get_branch()
+    if not is_pq_branch(current, options):
+        switch_to_pq_branch(repo, current, options)
+    patch = Patch(patchfile)
+    apply_and_commit_patch(repo, patch, fallback_author=None)
+
+
 def build_parser(name):
     """Construct command line parser"""
     try:
@@ -415,6 +465,7 @@ switch         Switch to patch-queue branch and vice versa.""")
     parser.add_config_file_option(option_name="spec-file", dest="spec_file")
     parser.add_config_file_option(option_name="packaging-dir",
             dest="packaging_dir")
+    parser.add_config_file_option(option_name="pq-branch", dest="pq_branch")
     parser.add_option("--export-rev", dest="export_rev",
             metavar="TREEISH",
             help="Export patches from treeish object TREEISH instead of head "
@@ -477,20 +528,18 @@ def main(argv):
     try:
         # Create base temporary directory for this run
         init_tmpdir(options.tmp_dir, prefix='pq-rpm_')
-        current = repo.get_branch()
         if action == "export":
             export_patches(repo, options)
         elif action == "import":
             import_spec_patches(repo, options)
         elif action == "drop":
-            drop_pq(repo, current, options)
+            drop_pq_rpm(repo, options)
         elif action == "rebase":
             rebase_pq(repo, options)
         elif action == "apply":
-            patch = Patch(patchfile)
-            apply_single_patch(repo, current, patch, None, options)
+            apply_single_patch(repo, patchfile, options)
         elif action == "switch":
-            switch_pq(repo, current, options)
+            switch_pq(repo, options)
     except CommandExecFailed:
         retval = 1
     except GitRepositoryError as err:
index 244f11bd186fdd72e052d9a1dfc7bdb6c5ee09c3..218107f920c3e30a2db1c57d52912ba920e4f73a 100644 (file)
@@ -74,17 +74,17 @@ class TestPqRpm(RpmRepoTestBase):
     def test_import_export(self):
         """Basic test for patch import and export"""
         repo = self.init_test_repo('gbp-test')
-        branches = repo.get_local_branches() + ['patch-queue/master']
+        branches = repo.get_local_branches() + ['development/master']
         # Test import
         eq_(mock_pq(['import']), 0)
         files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README',
                  'mydir/myfile.txt', '.gbp.conf']
-        branches.append('patch-queue/master')
-        self._check_repo_state(repo, 'patch-queue/master', branches, files)
-        eq_(repo.get_merge_base('upstream', 'patch-queue/master'),
+        branches.append('development/master')
+        self._check_repo_state(repo, 'development/master', branches, files)
+        eq_(repo.get_merge_base('upstream', 'development/master'),
             repo.rev_parse('upstream'))
         ok_(len(repo.get_commits('', 'upstream')) <
-            len(repo.get_commits('', 'patch-queue/master')))
+            len(repo.get_commits('', 'development/master')))
 
         # Test export
         eq_(mock_pq(['export']), 0)
@@ -102,13 +102,13 @@ class TestPqRpm(RpmRepoTestBase):
     def test_import_export2(self):
         """Another test for import and export"""
         repo = self.init_test_repo('gbp-test2')
-        branches = repo.get_local_branches() + ['patch-queue/master-orphan']
+        branches = repo.get_local_branches() + ['development/master-orphan']
         repo.set_branch('master-orphan')
         # Import
         eq_(mock_pq(['import']), 0)
         files = ['dummy.sh', 'Makefile', 'README', 'mydir/myfile.txt',
                  '.gbp.conf']
-        self._check_repo_state(repo, 'patch-queue/master-orphan', branches,
+        self._check_repo_state(repo, 'development/master-orphan', branches,
                                files)
 
         # Test export
@@ -120,66 +120,66 @@ class TestPqRpm(RpmRepoTestBase):
         """Test running gbp-rpm-pq from a subdir in the git tree"""
         repo = self.init_test_repo('gbp-test2')
         repo.set_branch('master-orphan')
-        branches = repo.get_local_branches() + ['patch-queue/master-orphan']
+        branches = repo.get_local_branches() + ['development/master-orphan']
         os.chdir('packaging')
 
         # Running from subdir should be ok
         eq_(mock_pq(['import']), 0)
-        self._check_repo_state(repo, 'patch-queue/master-orphan', branches)
+        self._check_repo_state(repo, 'development/master-orphan', branches)
 
 
     def test_rebase(self):
         """Basic test for rebase action"""
         repo = self.init_test_repo('gbp-test')
-        repo.rename_branch('pq/master', 'patch-queue/master')
-        repo.set_branch('patch-queue/master')
+        repo.rename_branch('pq/master', 'development/master')
+        repo.set_branch('development/master')
         branches = repo.get_local_branches()
         # Make development branch out-of-sync
         GitCommand("rebase")(['--onto', 'upstream^', 'upstream'])
         # Sanity check for our git rebase...
-        ok_(repo.get_merge_base('patch-queue/master', 'upstream') !=
+        ok_(repo.get_merge_base('development/master', 'upstream') !=
             repo.rev_parse('upstream'))
 
         # Do rebase
         eq_(mock_pq(['rebase']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
-        ok_(repo.get_merge_base('patch-queue/master', 'upstream') ==
+        self._check_repo_state(repo, 'development/master', branches)
+        ok_(repo.get_merge_base('development/master', 'upstream') ==
             repo.rev_parse('upstream'))
 
         # Get to out-of-sync, again, and try rebase from master branch
         GitCommand("rebase")(['--onto', 'upstream^', 'upstream'])
         eq_(mock_pq(['switch']), 0)
         eq_(mock_pq(['rebase']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
-        ok_(repo.get_merge_base('patch-queue/master', 'upstream') ==
+        self._check_repo_state(repo, 'development/master', branches)
+        ok_(repo.get_merge_base('development/master', 'upstream') ==
             repo.rev_parse('upstream'))
 
     def test_switch(self):
         """Basic test for switch action"""
         repo = self.init_test_repo('gbp-test')
         pkg_files = repo.list_files()
-        branches = repo.get_local_branches() + ['patch-queue/master']
+        branches = repo.get_local_branches() + ['development/master']
         # Switch to non-existent pq-branch should create one
         eq_(mock_pq(['switch']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
 
         # Switch to base branch and back to pq
         eq_(mock_pq(['switch']), 0)
         self._check_repo_state(repo, 'master', branches)
         eq_(mock_pq(['switch']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
 
     def test_switch_drop(self):
         """Basic test for drop action"""
         repo = self.init_test_repo('gbp-test')
-        repo.rename_branch('pq/master', 'patch-queue/master')
-        repo.set_branch('patch-queue/master')
+        repo.rename_branch('pq/master', 'development/master')
+        repo.set_branch('development/master')
         branches = repo.get_local_branches()
 
         # Drop pq should fail when on pq branch
         eq_(mock_pq(['drop']), 1)
         self._check_log(-1, "gbp:error: On a patch-queue branch, can't drop it")
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
 
         # Switch to master
         eq_(mock_pq(['switch']), 0)
@@ -187,28 +187,28 @@ class TestPqRpm(RpmRepoTestBase):
 
         # Drop should succeed when on master branch
         eq_(mock_pq(['drop']), 0)
-        branches.remove('patch-queue/master')
+        branches.remove('development/master')
         self._check_repo_state(repo, 'master', branches)
 
     def test_force_import(self):
         """Test force import"""
         repo = self.init_test_repo('gbp-test')
         pkg_files = repo.list_files()
-        repo.rename_branch('pq/master', 'patch-queue/master')
-        repo.set_branch('patch-queue/master')
+        repo.rename_branch('pq/master', 'development/master')
+        repo.set_branch('development/master')
         branches = repo.get_local_branches()
         pq_files = repo.list_files()
 
         # Re-import should fail
         eq_(mock_pq(['import']), 1)
         self._check_log(0, "gbp:error: Already on a patch-queue branch")
-        self._check_repo_state(repo, 'patch-queue/master', branches, pq_files)
+        self._check_repo_state(repo, 'development/master', branches, pq_files)
 
         # Mangle pq branch and try force import on top of that
         repo.force_head('master', hard=True)
-        self._check_repo_state(repo, 'patch-queue/master', branches, pkg_files)
+        self._check_repo_state(repo, 'development/master', branches, pkg_files)
         eq_(mock_pq(['import', '--force']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches, pq_files)
+        self._check_repo_state(repo, 'development/master', branches, pq_files)
 
         # Switch back to master
         eq_(mock_pq(['switch']), 0)
@@ -221,27 +221,27 @@ class TestPqRpm(RpmRepoTestBase):
 
         # Force import should succeed
         eq_(mock_pq(['import', '--force']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches, pq_files)
+        self._check_repo_state(repo, 'development/master', branches, pq_files)
 
     def test_apply(self):
         """Basic test for apply action"""
         repo = self.init_test_repo('gbp-test')
         upstr_files = ['dummy.sh', 'Makefile', 'README']
-        branches = repo.get_local_branches() + ['patch-queue/master']
+        branches = repo.get_local_branches() + ['development/master']
 
         # No patch given
         eq_(mock_pq(['apply']), 1)
         self._check_log(-1, "gbp:error: No patch name given.")
 
         # Create a pristine pq-branch
-        repo.create_branch('patch-queue/master', 'upstream')
+        repo.create_branch('development/master', 'upstream')
 
         # Apply patch
         with tempfile.NamedTemporaryFile() as tmp_patch:
             tmp_patch.write(repo.show('master:%s' % 'my.patch'))
             tmp_patch.file.flush()
             eq_(mock_pq(['apply', tmp_patch.name]), 0)
-            self._check_repo_state(repo, 'patch-queue/master', branches,
+            self._check_repo_state(repo, 'development/master', branches,
                                    upstr_files)
 
         # Apply another patch, now when already on pq branch
@@ -249,13 +249,13 @@ class TestPqRpm(RpmRepoTestBase):
             tmp_patch.write(repo.show('master:%s' % 'my2.patch'))
             tmp_patch.file.flush()
             eq_(mock_pq(['apply', tmp_patch.name]), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches,
+        self._check_repo_state(repo, 'development/master', branches,
                                upstr_files + ['mydir/myfile.txt'])
 
     def test_option_patch_numbers(self):
         """Test the --patch-numbers cmdline option"""
         repo = self.init_test_repo('gbp-test')
-        repo.rename_branch('pq/master', 'patch-queue/master')
+        repo.rename_branch('pq/master', 'development/master')
         branches = repo.get_local_branches()
         # Export
         eq_(mock_pq(['export', '--no-patch-numbers']), 0)
@@ -315,17 +315,42 @@ class TestPqRpm(RpmRepoTestBase):
         eq_(mock_pq(['export', '--packaging-dir=foo',
                      '--spec-file=gbp-test.spec']), 0)
 
+    def test_option_pq_branch(self):
+        """Test the --pq-branch option"""
+        repo = self.init_test_repo('gbp-test')
+        branches = repo.get_local_branches()
+
+        # Invalid branch name
+        eq_(mock_pq(['import', '--pq-branch=%(branch)s/foo:']), 1)
+        self._check_log(-1, "gbp:error: Cannot create patch-queue branch")
+
+        # Try all possible keys in pq-branch format string
+        eq_(mock_pq(['import',
+                     '--pq-branch=dev/%(branch)s/%(upstreamversion)s']), 0)
+        branches.append('dev/master/1.1')
+        self._check_repo_state(repo, 'dev/master/1.1', branches)
+
+        # Switch to non-existent packaging branch should fail
+        eq_(mock_pq(['switch', '--pq-branch=dev/master/1.1']), 1)
+        self._check_log(-1, "gbp:error: Invalid pq-branch, name format")
+        self._check_repo_state(repo, 'dev/master/1.1', branches)
+
+        # Switch to existing packaging branch should be ok
+        eq_(mock_pq(['switch',
+                     '--pq-branch=dev/%(branch)s/%(upstreamversion)s']), 0)
+        self._check_repo_state(repo, 'master', branches)
+
     def test_export_with_merges(self):
         """Test exporting pq-branch with merge commits"""
         repo = self.init_test_repo('gbp-test')
-        repo.rename_branch('pq/master', 'patch-queue/master')
-        repo.set_branch('patch-queue/master')
+        repo.rename_branch('pq/master', 'development/master')
+        repo.set_branch('development/master')
         branches = repo.get_local_branches()
 
         # Create a merge commit in pq-branch
         patches = repo.format_patches('HEAD^', 'HEAD', '.')
         repo.force_head('HEAD^', hard=True)
-        repo.commit_dir('.', 'Merge with master', 'patch-queue/master',
+        repo.commit_dir('.', 'Merge with master', 'development/master',
                         ['master'])
         merge_rev = repo.rev_parse('HEAD', short=7)
         eq_(mock_pq(['apply', patches[0]]), 0)
@@ -344,15 +369,15 @@ class TestPqRpm(RpmRepoTestBase):
         repo = self.init_test_repo('gbp-test')
 
         # Import with default settings (should import gbp conf files)
-        branches = repo.get_local_branches() + ['patch-queue/master']
+        branches = repo.get_local_branches() + ['development/master']
         eq_(mock_pq(['import']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
         ok_('.gbp.conf' in repo.list_files())
 
         # Re-import with user-defined files
         eq_(mock_pq(['import', '--force', '--import-files',
                      'foo.txt,my.patch']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
         ok_('foo.txt' in repo.list_files())
         ok_('my.patch' in repo.list_files())
 
@@ -360,7 +385,7 @@ class TestPqRpm(RpmRepoTestBase):
         eq_(mock_pq(['switch']), 0)
         eq_(mock_pq(['drop']), 0)
         eq_(mock_pq(['import', '--import-files=']), 0)
-        self._check_repo_state(repo, 'patch-queue/master', branches)
+        self._check_repo_state(repo, 'development/master', branches)
         ok_('debian/gbp.conf' not in repo.list_files())
         ok_('.gbp.conf' not in repo.list_files())