From a9bf9cfd4b31076c54d4e377c1b31b5bd69f8661 Mon Sep 17 00:00:00 2001 From: Daniel Dehennin Date: Wed, 30 May 2012 21:30:45 +0200 Subject: [PATCH] Move debian/changelog manipulation to gbp.deb.changelog.ChangeLog. spawn_dch switch gbp.command.wrappers.Command. * gbp/deb/changelog.py (ChangeLog.spawn_dch): static method adapted from gbp.scripts.dch and converted to gbp.command_wrappers.Command. (add_entry): New method adapted from gbp.scripts.dch.add_changelog_entry. (add_section): New method adapted from gbp.scripts.dch.add_changelog_entry. Remove DebianGitRepository and options, this has nothing to do with changelog management. * tests/test_Changelog.py: Test new methods. * gbp/scripts/dch.py: Remove useless functions: system(), spawn_dch(), add_changelog_section() and add_changelog_entry(). Update calls accordingly. (fixup_trailer): Use spawn_dch() method of ChangeLog class. (process_options): dch_options became a list. (main): Use add_section() and add_entry() methods of ChangeLog object. Take care of upstream version since ChangeLog.add_section() does not manage it anymore. Update exception handling, ChangeLog.spawn_dch() can raise "CommandExecFailed" exception. Closes: #672954 --- gbp/deb/changelog.py | 96 +++++++++++++++++++++++++++++++++++++ gbp/scripts/dch.py | 122 +++++++++--------------------------------------- tests/test_Changelog.py | 85 +++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 99 deletions(-) diff --git a/gbp/deb/changelog.py b/gbp/deb/changelog.py index b1be400..2d2f016 100644 --- a/gbp/deb/changelog.py +++ b/gbp/deb/changelog.py @@ -19,6 +19,7 @@ import email import os import subprocess +from gbp.command_wrappers import Command class NoChangeLogError(Exception): """No changelog found""" @@ -214,3 +215,98 @@ class ChangeLog(object): Get sections in the changelog """ return list(self.sections_iter) + + @staticmethod + def spawn_dch(msg=[], author=None, email=None, newversion=False, version=None, + release=False, distribution=None, dch_options=[]): + """ + Spawn dch + + @param author: committers name + @type author: C{str} + @param email: committers email + @type email: C{str} + @param newversion: start a new version + @type newversion: C{bool} + @param version: the verion to use + @type version: C{str} + @param release: finalize changelog for releaze + @type release: C{bool} + @param distribution: distribution to use + @type distribution: C{str} + @param dch_options: options passed verbatim to dch + @type dch_options: C{list} + """ + env = {} + args = ['--no-auto-nmu'] + if newversion: + if version: + try: + args.append(version['increment']) + except KeyError: + args.append('--newversion=%s' % version['version']) + else: + args.append('-i') + elif release: + args.extend(["--release", "--no-force-save-on-release"]) + msg = None + + if author and email: + env = {'DEBFULLNAME': author, 'DEBEMAIL': email} + + if distribution: + args.append("--distribution=%s" % distribution) + + args.extend(dch_options) + args.append('--') + if msg: + args.append('[[[insert-git-dch-commit-message-here]]]') + else: + args.append('') + dch = Command('dch', args, extra_env=env) + dch.call([]) + 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_entry(self, msg, author=None, email=None, dch_options=[]): + """Add a single changelog entry + + @param msg: log message to add + @type msg: C{str} + @param author: name of the author of the log message + @type author: C{str} + @param email: email of the author of the log message + @type email: C{str} + @param dch_options: options passed verbatim to dch + @type dch_options: C{list} + """ + self.spawn_dch(msg=msg, author=author, email=email, dch_options=dch_options) + + def add_section(self, msg, distribution, author=None, email=None, + version={}, dch_options=[]): + """Add a new section to the changelog + + @param msg: log message to add + @type msg: C{str} + @param distribution: distribution to set for the new changelog entry + @type distribution: C{str} + @param author: name of the author of the log message + @type author: C{str} + @param email: email of the author of the log message + @type email: C{str} + @param version: version to set for the new changelog entry + @param version: C{dict} + @param dch_options: options passed verbatim to dch + @type dch_options: C{list} + """ + self.spawn_dch(msg=msg, newversion=True, version=version, author=author, + email=email, distribution=distribution, dch_options=dch_options) diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 86c0547..b31a67b 100644 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -35,72 +35,6 @@ user_customizations = {} snapshot_re = re.compile("\s*\*\* SNAPSHOT build @(?P[a-z0-9]+)\s+\*\*") -def system(cmd): - try: - gbpc.Command(cmd, shell=True)() - except gbpc.CommandExecFailed: - raise GbpError - - -def spawn_dch(msg=[], author=None, email=None, newversion=False, version=None, - release=False, distribution=None, dch_options=''): - """ - Spawn dch - - @param author: committers name - @param email: committers email - @param newversion: start a new version - @param version: the verion to use - @param release: finalize changelog for releaze - @param distribution: distribution to use - @param dch_options: options passed verbatim to dch - """ - distopt = "" - versionopt = "" - env = "" - - if newversion: - if version: - try: - versionopt = version['increment'] - except KeyError: - versionopt = '--newversion=%s' % version['version'] - else: - versionopt = '-i' - elif release: - versionopt = "--release --no-force-save-on-release" - msg = None - - if author and email: - env = """DEBFULLNAME="%s" DEBEMAIL="%s" """ % (author, email) - - if distribution: - distopt = "--distribution=%s" % distribution - - cmd = '%(env)s dch --no-auto-nmu %(distopt)s %(versionopt)s %(dch_options)s ' % locals() - 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): - """Add a single changelog entry""" - spawn_dch(msg=msg, author=author, email=email, dch_options=dch_options) - - def guess_version_from_upstream(repo, upstream_tag_format, cp): """ Guess the version based on the latest version on the upstream branch @@ -116,17 +50,6 @@ def guess_version_from_upstream(repo, upstream_tag_format, cp): return None -def add_changelog_section(msg, distribution, repo, options, cp, - author=None, email=None, version={}, dch_options=''): - """Add a new section to the changelog""" - if not version and not cp.is_native(): - v = guess_version_from_upstream(repo, options.upstream_tag, cp) - if v: - version['version'] = v - spawn_dch(msg=msg, newversion=True, version=version, author=author, - email=email, distribution=distribution, dch_options=dch_options) - - def get_author_email(repo, use_git_config): """Get author and email from git configuration""" author = email = None @@ -148,7 +71,7 @@ def fixup_trailer(repo, git_author, dch_options): creating the changelog """ author, email = get_author_email(repo, git_author) - spawn_dch(msg='', author=author, email=email, dch_options=dch_options) + ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options) def snapshot_version(version): @@ -221,7 +144,7 @@ def do_release(changelog, repo, cp, git_author, dch_options): if snapshot: cp['MangledVersion'] = release mangle_changelog(changelog, cp) - spawn_dch(release=True, author=author, email=email, dch_options=dch_options) + cp.spawn_dch(release=True, author=author, email=email, dch_options=dch_options) def do_snapshot(changelog, repo, next_snapshot): @@ -289,15 +212,16 @@ def process_options(options, parser): if options.since and options.auto: parser.error("'--since' and '--auto' are incompatible options") + dch_options = [] if options.multimaint_merge: - dch_options = "--multimaint-merge" + dch_options.append("--multimaint-merge") else: - dch_options = "--nomultimaint-merge" + dch_options.append("--nomultimaint-merge") if options.multimaint: - dch_options += " --multimaint" + dch_options.append("--multimaint") else: - dch_options += " --nomultimaint" + dch_options.append("--nomultimaint") get_customizations(options.customization_file) return dch_options @@ -480,6 +404,12 @@ def main(argv): else: add_section = False + if add_section and not version_change and not cp.is_native(): + # Get version from upstream if none provided + v = guess_version_from_upstream(repo, options.upstream_tag, cp) + if v: + version_change['version'] = v + i = 0 for c in commits: i += 1 @@ -493,18 +423,15 @@ def main(argv): if add_section: # Add a section containing just this message (we can't # add an empty section with dch) - add_changelog_section(distribution="UNRELEASED", msg=commit_msg, - version=version_change, - author=commit_author, - email=commit_email, - dch_options=dch_options, - repo=repo, - options=options, - cp=cp) + cp.add_section(distribution="UNRELEASED", msg=commit_msg, + version=version_change, + author=commit_author, + email=commit_email, + dch_options=dch_options) # Adding a section only needs to happen once. add_section = False else: - add_changelog_entry(commit_msg, commit_author, commit_email, dch_options) + cp.add_entry(commit_msg, commit_author, commit_email, dch_options) # Show a message if there were no commits (not even ignored @@ -515,12 +442,9 @@ 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"], - version=version_change, - dch_options=dch_options, - repo=repo, - options=options, - cp=cp) + cp.add_section(distribution="UNRELEASED", msg=["UNRELEASED"], + version=version_change, + dch_options=dch_options) fixup_trailer(repo, git_author=options.git_author, dch_options=dch_options) @@ -545,7 +469,7 @@ def main(argv): repo.commit_files([changelog], msg) gbp.log.info("Changelog has been committed for version %s" % version) - except (GbpError, GitRepositoryError, NoChangeLogError) as err: + except (gbpc.CommandExecFailed, GbpError, GitRepositoryError, NoChangeLogError) as err: if len(err.__str__()): gbp.log.err(err) ret = 1 diff --git a/tests/test_Changelog.py b/tests/test_Changelog.py index c67aaa0..5516d03 100644 --- a/tests/test_Changelog.py +++ b/tests/test_Changelog.py @@ -223,3 +223,88 @@ def test_parse_sections(): >>> cl.sections[1].version '0.5.31' """ + +def test_add_section(): + """ + Test if we can add a section to an existant changelog + + Methods tested: + - L{gbp.deb.changelog.ChangeLog.__init__} + - L{gbp.deb.changelog.ChangeLog._parse} + - L{gbp.deb.changelog.ChangeLog.add_section} + - L{gbp.deb.changelog.ChangeLog.spawn_dch} + + >>> import os + >>> import tempfile + >>> import shutil + >>> import gbp.deb.changelog + >>> olddir = os.path.abspath(os.path.curdir) + >>> testdir = tempfile.mkdtemp(prefix='gbp-test-changelog-') + >>> testdebdir = os.path.join(testdir, 'debian') + >>> testclname = os.path.join(testdebdir, "changelog") + >>> os.mkdir(testdebdir) + >>> clh = open(os.path.join(testdebdir, "changelog"), "w") + >>> clh.write(cl_debian) + >>> clh.close() + >>> os.chdir(testdir) + >>> os.path.abspath(os.path.curdir) == testdir + True + >>> cl = gbp.deb.changelog.ChangeLog(filename=testclname) + >>> cl.add_section(msg=["Test add section"], distribution=None, author="Debian Maintainer", email="maint@debian.org") + >>> cl = gbp.deb.changelog.ChangeLog(filename=testclname) + >>> cl.version + '0.5.33' + >>> cl.debian_version + '0.5.33' + >>> cl['Distribution'] + 'UNRELEASED' + >>> 'Test add section' in cl['Changes'] + True + >>> os.chdir(olddir) + >>> os.path.abspath(os.path.curdir) == olddir + True + >>> shutil.rmtree(testdir, ignore_errors=True) + """ + +def test_add_entry(): + """ + Test if we can add an entry to an existant changelog + + Methods tested: + - L{gbp.deb.changelog.ChangeLog.__init__} + - L{gbp.deb.changelog.ChangeLog._parse} + - L{gbp.deb.changelog.ChangeLog.add_entry} + - L{gbp.deb.changelog.ChangeLog.spawn_dch} + + >>> import os + >>> import tempfile + >>> import shutil + >>> import gbp.deb.changelog + >>> olddir = os.path.abspath(os.path.curdir) + >>> testdir = tempfile.mkdtemp(prefix='gbp-test-changelog-') + >>> testdebdir = os.path.join(testdir, 'debian') + >>> testclname = os.path.join(testdebdir, "changelog") + >>> os.mkdir(testdebdir) + >>> clh = open(os.path.join(testdebdir, "changelog"), "w") + >>> clh.write(cl_debian) + >>> clh.close() + >>> os.chdir(testdir) + >>> os.path.abspath(os.path.curdir) == testdir + True + >>> cl = gbp.deb.changelog.ChangeLog(filename=testclname) + >>> cl.add_section(msg=["Test add section"], distribution=None, author="Debian Maintainer", email="maint@debian.org") + >>> cl.add_entry(msg=["Test add entry"], author="Debian Maintainer", email="maint@debian.org") + >>> cl = gbp.deb.changelog.ChangeLog(filename=testclname) + >>> cl.version + '0.5.33' + >>> cl.debian_version + '0.5.33' + >>> cl['Distribution'] + 'UNRELEASED' + >>> 'Test add entry' in cl['Changes'] + True + >>> os.chdir(olddir) + >>> os.path.abspath(os.path.curdir) == olddir + True + >>> shutil.rmtree(testdir, ignore_errors=True) + """ -- 2.7.4