aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2012-01-12 15:41:46 +0200
committerGuido Günther <agx@sigxcpu.org>2012-04-18 22:36:48 +0200
commit9c4f34c5b94ddd3e78a0c6ef94cf7c6afd9a8ada (patch)
tree44c4b9cc572d1b48e9d7237766d5579d51837db9
parent19b6e245cbf8e4954bb72ac0d44a82facdf76858 (diff)
Refactor gbp-pq as preparation for rpm support
Separate some functions of gbp-pq into a basemodule, intended to be re-used by the upcoming rpm variant of the tool. Also, introduces a new python subpackage gbp.scripts.common to be used for the re-usable parts of the scripts in the refactoring work.
-rw-r--r--gbp/scripts/common/__init__.py0
-rw-r--r--gbp/scripts/common/pq.py190
-rwxr-xr-xgbp/scripts/pq.py164
3 files changed, 194 insertions, 160 deletions
diff --git a/gbp/scripts/common/__init__.py b/gbp/scripts/common/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gbp/scripts/common/__init__.py
diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py
new file mode 100644
index 0000000..e2293e8
--- /dev/null
+++ b/gbp/scripts/common/pq.py
@@ -0,0 +1,190 @@
+# vim: set fileencoding=utf-8 :
+#
+# (C) 2011 Guido Günther <agx@sigxcpu.org>
+# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+"""Common functionality for Debian and RPM patchqueue management"""
+
+import re
+import os
+import shutil
+import subprocess
+from gbp.git import (GitRepositoryError, GitRepository)
+from gbp.command_wrappers import (Command, GitCommand, RunAtCommand,
+ CommandExecFailed)
+from gbp.errors import GbpError
+import gbp.log
+from gbp.patch_series import (PatchSeries, Patch)
+
+PQ_BRANCH_PREFIX = "patch-queue/"
+
+
+def is_pq_branch(branch):
+ """
+ is branch a patch-queue branch?
+
+ >>> is_pq_branch("foo")
+ False
+ >>> is_pq_branch("patch-queue/foo")
+ True
+ """
+ return [False, True][branch.startswith(PQ_BRANCH_PREFIX)]
+
+
+def pq_branch_name(branch):
+ """
+ get the patch queue branch corresponding to branch
+
+ >>> pq_branch_name("patch-queue/master")
+ >>> pq_branch_name("foo")
+ 'patch-queue/foo'
+ """
+ if not is_pq_branch(branch):
+ return PQ_BRANCH_PREFIX + branch
+
+
+def pq_branch_base(pq_branch):
+ """
+ get the branch corresponding to the given patch queue branch
+
+ >>> pq_branch_base("patch-queue/master")
+ 'master'
+ >>> pq_branch_base("foo")
+ """
+ if is_pq_branch(pq_branch):
+ return pq_branch[len(PQ_BRANCH_PREFIX):]
+
+
+def write_patch(patch, patch_dir, options):
+ """Write the patch exported by 'git-format-patch' to it's final location
+ (as specified in the commit)"""
+ oldname = os.path.basename(patch)
+ newname = oldname
+ tmpname = patch + ".gbp"
+ old = file(patch, 'r')
+ tmp = file(tmpname, 'w')
+ in_patch = False
+ topic = None
+
+ # Skip first line (From <sha1>)
+ old.readline()
+ for line in old:
+ if line.lower().startswith("gbp-pq-topic: "):
+ topic = line.split(" ",1)[1].strip()
+ gbp.log.debug("Topic %s found for %s" % (topic, patch))
+ continue
+ tmp.write(line)
+ tmp.close()
+ old.close()
+
+ if not options.patch_numbers:
+ patch_re = re.compile("[0-9]+-(?P<name>.+)")
+ m = patch_re.match(oldname)
+ if m:
+ newname = m.group('name')
+
+ if topic:
+ topicdir = os.path.join(patch_dir, topic)
+ else:
+ topicdir = patch_dir
+
+ if not os.path.isdir(topicdir):
+ os.makedirs(topicdir, 0755)
+
+ os.unlink(patch)
+ dstname = os.path.join(topicdir, newname)
+ gbp.log.debug("Moving %s to %s" % (tmpname, dstname))
+ shutil.move(tmpname, dstname)
+
+ return dstname
+
+
+def get_maintainer_from_control():
+ """Get the maintainer from the control file"""
+ cmd = 'sed -n -e \"s/Maintainer: \\+\\(.*\\)/\\1/p\" debian/control'
+ cmdout = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.readlines()
+
+ if len(cmdout) > 0:
+ maintainer = cmdout[0].strip()
+ m = re.match('(?P<name>.*[^ ]) *<(?P<email>.*)>', maintainer)
+ if m:
+ return m.group('name'), m.group('email')
+
+ return None, None
+
+
+def switch_to_pq_branch(repo, branch):
+ """
+ Switch to patch-queue branch if not already there, create it if it
+ doesn't exist yet
+ """
+ if is_pq_branch (branch):
+ return
+
+ pq_branch = pq_branch_name(branch)
+ if not repo.has_branch(pq_branch):
+ try:
+ repo.create_branch(pq_branch)
+ except CommandExecFailed:
+ raise GbpError, ("Cannot create patch-queue branch '%s'. Try 'rebase' instead."
+ % pq_branch)
+
+ gbp.log.info("Switching to '%s'" % pq_branch)
+ repo.set_branch(pq_branch)
+
+
+def apply_single_patch(repo, branch, patch, topic=None):
+ switch_to_pq_branch(repo, branch)
+ apply_and_commit_patch(repo, patch, topic)
+
+
+def apply_and_commit_patch(repo, patch, topic=None):
+ """apply a single patch 'patch', add topic 'topic' and commit it"""
+ author = { 'name': patch.author,
+ 'email': patch.email,
+ 'date': patch.date }
+
+ if not (patch.author and patch.email):
+ name, email = get_maintainer_from_control()
+ if name:
+ gbp.log.warn("Patch '%s' has no authorship information, "
+ "using '%s <%s>'" % (patch.path, name, email))
+ author['name'] = name
+ author['email'] = email
+ else:
+ gbp.log.warn("Patch %s has no authorship information")
+
+ repo.apply_patch(patch.path)
+ tree = repo.write_tree()
+ msg = "%s\n\n%s" % (patch.subject, patch.long_desc)
+ if topic:
+ msg += "\nGbp-Pq-Topic: %s" % topic
+ commit = repo.commit_tree(tree, msg, [repo.head], author=author)
+ repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
+
+
+def drop_pq(repo, branch):
+ if is_pq_branch(branch):
+ gbp.log.err("On a patch-queue branch, can't drop it.")
+ raise GbpError
+ else:
+ pq_branch = pq_branch_name(branch)
+
+ if repo.has_branch(pq_branch):
+ repo.delete_branch(pq_branch)
+ gbp.log.info("Dropped branch '%s'." % pq_branch)
+ else:
+ gbp.log.info("No patch queue branch found - doing nothing.")
diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py
index ad94525..2fcc0c8 100755
--- a/gbp/scripts/pq.py
+++ b/gbp/scripts/pq.py
@@ -18,10 +18,8 @@
"""manage patches in a patch queue"""
import errno
-import re
import os
import shutil
-import subprocess
import sys
import tempfile
from gbp.config import (GbpOptionParserDebian, GbpOptionGroup)
@@ -31,91 +29,15 @@ from gbp.command_wrappers import (Command, GitCommand, RunAtCommand,
from gbp.errors import GbpError
import gbp.log
from gbp.patch_series import (PatchSeries, Patch)
+from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base,
+ write_patch, switch_to_pq_branch,
+ apply_single_patch, apply_and_commit_patch,
+ drop_pq)
-PQ_BRANCH_PREFIX = "patch-queue/"
PATCH_DIR = "debian/patches/"
SERIES_FILE = os.path.join(PATCH_DIR,"series")
-def is_pq_branch(branch):
- """
- is branch a patch-queue branch?
-
- >>> is_pq_branch("foo")
- False
- >>> is_pq_branch("patch-queue/foo")
- True
- """
- return [False, True][branch.startswith(PQ_BRANCH_PREFIX)]
-
-
-def pq_branch_name(branch):
- """
- get the patch queue branch corresponding to branch
-
- >>> pq_branch_name("patch-queue/master")
- >>> pq_branch_name("foo")
- 'patch-queue/foo'
- """
- if not is_pq_branch(branch):
- return PQ_BRANCH_PREFIX + branch
-
-
-def pq_branch_base(pq_branch):
- """
- get the branch corresponding to the given patch queue branch
-
- >>> pq_branch_base("patch-queue/master")
- 'master'
- >>> pq_branch_base("foo")
- """
- if is_pq_branch(pq_branch):
- return pq_branch[len(PQ_BRANCH_PREFIX):]
-
-def write_patch(patch, patch_dir, options):
- """Write the patch exported by 'git-format-patch' to it's final location
- (as specified in the commit)"""
- oldname = os.path.basename(patch)
- newname = oldname
- tmpname = patch + ".gbp"
- old = file(patch, 'r')
- tmp = file(tmpname, 'w')
- in_patch = False
- topic = None
-
- # Skip first line (From <sha1>)
- old.readline()
- for line in old:
- if line.lower().startswith("gbp-pq-topic: "):
- topic = line.split(" ",1)[1].strip()
- gbp.log.debug("Topic %s found for %s" % (topic, patch))
- continue
- tmp.write(line)
- tmp.close()
- old.close()
-
- if not options.patch_numbers:
- patch_re = re.compile("[0-9]+-(?P<name>.+)")
- m = patch_re.match(oldname)
- if m:
- newname = m.group('name')
-
- if topic:
- topicdir = os.path.join(patch_dir, topic)
- else:
- topicdir = patch_dir
-
- if not os.path.isdir(topicdir):
- os.makedirs(topicdir, 0755)
-
- os.unlink(patch)
- dstname = os.path.join(topicdir, newname)
- gbp.log.debug("Moving %s to %s" % (tmpname, dstname))
- shutil.move(tmpname, dstname)
-
- return dstname
-
-
def export_patches(repo, branch, options):
"""Export patches from the pq branch into a patch series"""
if is_pq_branch(branch):
@@ -148,20 +70,6 @@ def export_patches(repo, branch, options):
gbp.log.info("No patches on '%s' - nothing to do." % pq_branch)
-def get_maintainer_from_control():
- """Get the maintainer from the control file"""
- cmd = 'sed -n -e \"s/Maintainer: \\+\\(.*\\)/\\1/p\" debian/control'
- cmdout = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.readlines()
-
- if len(cmdout) > 0:
- maintainer = cmdout[0].strip()
- m = re.match('(?P<name>.*[^ ]) *<(?P<email>.*)>', maintainer)
- if m:
- return m.group('name'), m.group('email')
-
- return None, None
-
-
def safe_patches(series):
"""
Safe the current patches in a temporary directory
@@ -251,70 +159,6 @@ def import_quilt_patches(repo, branch, series, tries, force):
shutil.rmtree(tmpdir)
-def switch_to_pq_branch(repo, branch):
- """
- Switch to patch-queue branch if not already there, create it if it
- doesn't exist yet
- """
- if is_pq_branch (branch):
- return
-
- pq_branch = pq_branch_name(branch)
- if not repo.has_branch(pq_branch):
- try:
- repo.create_branch(pq_branch)
- except CommandExecFailed:
- raise GbpError, ("Cannot create patch-queue branch '%s'. Try 'rebase' instead."
- % pq_branch)
-
- gbp.log.info("Switching to '%s'" % pq_branch)
- repo.set_branch(pq_branch)
-
-
-def apply_single_patch(repo, branch, patch, topic=None):
- switch_to_pq_branch(repo, branch)
- apply_and_commit_patch(repo, patch, topic)
-
-
-def apply_and_commit_patch(repo, patch, topic=None):
- """apply a single patch 'patch', add topic 'topic' and commit it"""
- author = { 'name': patch.author,
- 'email': patch.email,
- 'date': patch.date }
-
- if not (patch.author and patch.email):
- name, email = get_maintainer_from_control()
- if name:
- gbp.log.warn("Patch '%s' has no authorship information, "
- "using '%s <%s>'" % (patch.path, name, email))
- author['name'] = name
- author['email'] = email
- else:
- gbp.log.warn("Patch %s has no authorship information")
-
- repo.apply_patch(patch.path)
- tree = repo.write_tree()
- msg = "%s\n\n%s" % (patch.subject, patch.long_desc)
- if topic:
- msg += "\nGbp-Pq-Topic: %s" % topic
- commit = repo.commit_tree(tree, msg, [repo.head], author=author)
- repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
-
-
-def drop_pq(repo, branch):
- if is_pq_branch(branch):
- gbp.log.err("On a patch-queue branch, can't drop it.")
- raise GbpError
- else:
- pq_branch = pq_branch_name(branch)
-
- if repo.has_branch(pq_branch):
- repo.delete_branch(pq_branch)
- gbp.log.info("Dropped branch '%s'." % pq_branch)
- else:
- gbp.log.info("No patch queue branch found - doing nothing.")
-
-
def rebase_pq(repo, branch):
if is_pq_branch(branch):
base = pq_branch_base(branch)