aboutsummaryrefslogtreecommitdiffhomepage
path: root/git-dch
diff options
context:
space:
mode:
authorRob Browning <rlb@defaultvalue.org>2010-12-06 08:30:22 +0100
committerGuido Günther <agx@sigxcpu.org>2010-12-06 09:17:04 +0100
commit3640569c90a3326aa8b882fa72d63ed881785de4 (patch)
treede2c96284fadad8e87b4c258202b68a526d7b905 /git-dch
parente8757040c20697c7cce1180127e257f9f17ab713 (diff)
Add git-dch --customizations FILE to allow changelog entry customization
Add support for git-dch --customizations FILE. FILE must be Python code, and for now, the only useful thing it can do is define a format_changelog_entry() function which will override gbp.dch.format_changelog_entry(). Add a new customization option group for --customizations. Create a gbp.dch module and move the changelog entry formatting functions there. Create separate procedures to handle extracting metadata from the git log, and use them in the default format_changelog_entry(). These functions are also available for use by custom formatters: extract_git_dch_cmds(), filter_ignore_rx_matches(), extract_bts_cmds(), extract_thanks_info(), etc. Add a GitRepository.get_commit_info() method, and use it in git-dch parse_commit(). Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Diffstat (limited to 'git-dch')
-rwxr-xr-xgit-dch143
1 files changed, 47 insertions, 96 deletions
diff --git a/git-dch b/git-dch
index 1688a0af..4ec8a413 100755
--- a/git-dch
+++ b/git-dch
@@ -25,6 +25,7 @@ import sys
import shutil
import subprocess
import gbp.command_wrappers as gbpc
+import gbp.dch as dch
import gbp.log
from gbp.git import (GitRepositoryError, GitRepository, build_tag, tag_to_version)
from gbp.config import GbpOptionParser, GbpOptionGroup
@@ -32,10 +33,9 @@ from gbp.errors import GbpError
from gbp.deb import parse_changelog, NoChangelogError, is_native, compare_versions
from gbp.command_wrappers import (Command, CommandExecFailed)
+user_customizations = {}
snapshot_re = re.compile("\s*\*\* SNAPSHOT build @(?P<commit>[a-z0-9]+)\s+\*\*")
-author_re = re.compile('Author: (?P<author>.*) <(?P<email>.*)>')
-bug_r = r'(?:bug|issue)?\#?\s?\d+'
-bug_re = re.compile(bug_r, re.I)
+
def system(cmd):
try:
@@ -44,29 +44,7 @@ def system(cmd):
raise GbpError
-def escape_commit(msg):
- return msg.replace('"','\\\"').replace("$","\$").replace("`","\`")
-
-def ispunct(ch):
- return not ch.isalnum() and not ch.isspace()
-
-def punctuate_commit(msg):
- """Terminate the first line of a commit message with a '.' if it's a
- multiline commit"""
- lines = msg.split('\n', 1)
- if len(lines) <= 1:
- return msg
- first, rest = lines
- # Don't add a dot on one line commit messages
- if not rest:
- return msg
- if first and ispunct(first[-1]):
- return msg
- if ispunct(rest[0]) or rest[0].islower():
- return msg
- return "%s.\n%s" % (first, rest)
-
-def spawn_dch(msg='', author=None, email=None, newversion=False, version=None,
+def spawn_dch(msg=[], author=None, email=None, newversion=False, version=None,
release=False, distribution=None, dch_options=''):
"""
Spawn dch
@@ -94,9 +72,6 @@ def spawn_dch(msg='', author=None, email=None, newversion=False, version=None,
versionopt = "--release --no-force-save-on-release"
msg = None
- if msg:
- msg = punctuate_commit(msg)
-
if author and email:
env = """DEBFULLNAME="%s" DEBEMAIL="%s" """ % (author, email)
@@ -104,9 +79,22 @@ def spawn_dch(msg='', author=None, email=None, newversion=False, version=None,
distopt = "--distribution=%s" % distribution
cmd = '%(env)s dch --no-auto-nmu %(distopt)s %(versionopt)s %(dch_options)s ' % locals()
- if type(msg) == type(''):
- cmd += '-- "%s"' % escape_commit(msg)
+ if msg:
+ cmd += '-- "[[[insert-git-dch-commit-message-here]]]"'
+ else:
+ cmd += '-- ""'
system(cmd)
+ if msg:
+ old_cl = open("debian/changelog", "r")
+ new_cl = open("debian/changelog.bak", "w")
+ for line in old_cl:
+ if line == " * [[[insert-git-dch-commit-message-here]]]\n":
+ print >> new_cl, " * " + msg[0]
+ for line in msg[1:]:
+ print >> new_cl, " " + line
+ else:
+ print >> new_cl, line,
+ os.rename("debian/changelog.bak", "debian/changelog")
def add_changelog_entry(msg, author, email, dch_options):
@@ -242,69 +230,16 @@ def do_snapshot(changelog, repo, next_snapshot):
return snapshot, commit
-def get_author(commit):
- """get the author from a commit message"""
- for line in commit:
- m = author_re.match(line)
- if m:
- return m.group('author'), m.group('email')
-
-
-def parse_commit(repo, commitid, options):
- """parse a commit and return message and author"""
- msg = ''
- thanks = ''
- closes = ''
- git_dch = ''
- bugs = {}
- bts_closes = re.compile(r'(?P<bts>%s):\s+%s' % (options.meta_closes, bug_r), re.I)
-
- if options.ignore_regex: # Ignore r'' since it matches everything
- ignore_re = re.compile(options.ignore_regex)
- else:
- ignore_re = None
-
- commit = repo.show(commitid)
- author, email = get_author(commit)
- if not author:
- raise GbpError, "can't parse author of commit %s" % commit
- for line in commit:
- if line.startswith(' '): # commit body
- line = line[4:]
- m = bts_closes.match(line)
- if m:
- bug_nums = [ bug.strip() for bug in bug_re.findall(line, re.I) ]
- try:
- bugs[m.group('bts')] += bug_nums
- except KeyError:
- bugs[m.group('bts')] = bug_nums
- elif line.startswith('Thanks: '):
- thanks = line.split(' ', 1)[1].strip()
- elif line.startswith('Git-Dch: '):
- git_dch = line.split(' ', 1)[1].strip()
- else: # normal commit message
- if msg and not options.full:
- continue
- if ignore_re and ignore_re.match(line):
- continue
- if line.strip(): # don't add all whitespace lines
- msg += line
- # start of diff output:
- elif line.startswith('diff '):
- break
- if options.meta:
- if git_dch == 'Ignore':
- return None
- if git_dch == 'Short':
- msg = msg.split('\n')[0]
- for bts in bugs:
- closes += '(%s: %s) ' % (bts, ', '.join(bugs[bts]))
- if thanks:
- thanks = '- thanks to %s' % thanks
- msg += closes + thanks
- if options.idlen:
- msg = "[%s] " % commitid[0:options.idlen] + msg
- return msg, (author, email)
+def parse_commit(repo, commitid, opts, last_commit=False):
+ """parse a commit and return message, author, and author email"""
+ commit_info = repo.get_commit_info(commitid)
+ author = commit_info['author']
+ email = commit_info['email']
+ format_entry = user_customizations.get('format_changelog_entry')
+ if not format_entry:
+ format_entry = dch.format_changelog_entry
+ entry = format_entry(commit_info, opts, last_commit=last_commit)
+ return entry, (author, email)
def guess_snapshot_commit(cp, repo, options):
@@ -347,10 +282,12 @@ def main(argv):
version_group = GbpOptionGroup(parser, "release & version number options", "what version number and release to use")
commit_group = GbpOptionGroup(parser, "commit message formatting", "howto format the changelog entries")
naming_group = GbpOptionGroup(parser, "branch and tag naming", "branch names and tag formats")
+ custom_group = GbpOptionGroup(parser, "customization", "options for customization")
parser.add_option_group(range_group)
parser.add_option_group(version_group)
parser.add_option_group(commit_group)
parser.add_option_group(naming_group)
+ parser.add_option_group(custom_group)
parser.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch")
naming_group.add_config_file_option(option_name="debian-branch", dest="debian_branch")
@@ -390,6 +327,13 @@ def main(argv):
help="Ignore commit lines matching regex, default is '%(ignore-regex)s'")
commit_group.add_boolean_config_file_option(option_name="multimaint-merge", dest="multimaint_merge")
+ help_msg = 'Load Python code from CUSTOMIZATION_FILE. At the moment,' \
+ + ' the only useful thing the code can do is define a custom' \
+ + ' format_changelog_entry() function.'
+ custom_group.add_config_file_option(option_name="customizations",
+ dest="customization_file",
+ help=help_msg)
+
(options, args) = parser.parse_args(argv[1:])
gbp.log.setup(options.color, options.verbose)
@@ -404,6 +348,10 @@ def main(argv):
else:
dch_options = "--nomultimaint-merge"
+ if options.customization_file:
+ execfile(options.customization_file,
+ user_customizations,
+ user_customizations)
try:
try:
repo = GitRepository('.')
@@ -458,8 +406,11 @@ def main(argv):
else:
add_section = False
+ i = 0
for c in commits:
- parsed = parse_commit(repo, c, options)
+ i += 1
+ parsed = parse_commit(repo, c, options,
+ last_commit = i == len(commits))
if not parsed:
# Some commits can be ignored
continue
@@ -490,7 +441,7 @@ def main(argv):
if add_section:
# If we end up here, then there were no commits to include,
# so we put a dummy message in the new section.
- add_changelog_section(distribution="UNRELEASED", msg="UNRELEASED",
+ add_changelog_section(distribution="UNRELEASED", msg=["UNRELEASED"],
version=version_change,
dch_options=dch_options,
repo=repo,