From: Markus Lehtonen Date: Thu, 27 Mar 2014 09:20:43 +0000 (+0200) Subject: changelog: utilize rpm-ch from git-buildpackage X-Git-Tag: 0.22~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0b452c4c143598664db93f8d87d2b946ede97f47;p=tools%2Fgbs.git changelog: utilize rpm-ch from git-buildpackage Start to use the gbp changelog tool as backend as it is more feature-rich. For example, it automatically parses bug-tracking-system meta-tags from the commit messages (i.e. "Closes: XYZ" etc) and has a lot more intelligent start-commit guessing. Later on, additional features from gbp can be enabled in gbs, too. Creating a new changelog from scratch now requires giving the --since option. Previously gbs would take the whole git history to the changelog which is problematic - e.g. creating a new changelog for linux kernel would take every commit from the linux git history which is *very* long. Also, the order of entries (i.e. commits) in the new changelog section is now reversed: the oldest commit will be first (topmost) in the list and the newest commit will be at the bottom of the list. This should make the changelog a better chronological read. Change-Id: Ib4f02f9be95f869b2161d16f8b68f828c5c1deda Signed-off-by: Markus Lehtonen --- diff --git a/gitbuildsys/cmd_changelog.py b/gitbuildsys/cmd_changelog.py index a1f17fd..7cb588b 100644 --- a/gitbuildsys/cmd_changelog.py +++ b/gitbuildsys/cmd_changelog.py @@ -19,86 +19,18 @@ """Implementation of subcmd: changelog """ -import os -import datetime import glob -from gitbuildsys.utils import guess_spec, edit_file +from gitbuildsys.utils import guess_spec, get_editor_cmd from gitbuildsys.cmd_export import get_packaging_dir from gitbuildsys.errors import GbsError from gitbuildsys.log import LOGGER as log from gbp.rpm.git import GitRepositoryError, RpmGitRepository +from gbp.scripts.rpm_changelog import main as gbp_rpm_ch -def get_all_entries(changesfile, new_entries): - """return all entries including old in changesfile and new_entries""" - lines = ["%s%s" % (line, os.linesep) for line in new_entries] - lines.append(os.linesep) - - if os.path.exists(changesfile): - with open(changesfile) as chlog: - lines.extend(chlog.readlines()) - return ''.join(lines) - - -def get_latest_rev(changesfile): - """Get latest git revision from the changelog.""" - if os.path.exists(changesfile): - with open(changesfile) as chlog: - line = chlog.readline() - return line.strip().split(" ")[-1].split("@")[-1] - return '' - -def get_version(git_repo, commit): - """ - Construct version from commit using rev-parse. - Set version to @ or if tag is not found. - """ - version = git_repo.rev_parse(commit, short=7) - try: - version = "%s@%s" % (git_repo.find_tag(commit), version) - except GitRepositoryError: - pass - - return version - -def make_log_entries(commits, git_repo): - """Make changelog entries from the set of git commits.""" - entries = [] - # Add header - author = git_repo.get_author_info() - entries.append("* %s %s <%s> %s" % \ - (datetime.datetime.now().strftime("%a %b %d %Y"), - author.name, author.email, get_version(git_repo, - commits[0]))) - for commit in commits: - commit_info = git_repo.get_commit_info(commit) - entries.append("- %s" % commit_info["subject"]) - return entries - -def get_first_commit(repo, changes, since): - """ - Get first commit considering since parameter and latest - git revision mentioned in .changes file. - """ - if since: - first = since - else: - first = get_latest_rev(changes) - - if first: - try: - return repo.rev_parse(first) - except GitRepositoryError: - if since: - raise GbsError("Invalid commit: %s" % (first)) - else: - raise GbsError("Can't find last commit ID in the log, "\ - "please specify it by '--since'") - - def main(args): """gbs changelog entry point.""" @@ -108,43 +40,36 @@ def main(args): raise GbsError(str(err)) packaging_dir = get_packaging_dir(args) + specfile = guess_spec(repo.path, packaging_dir, args.spec)[0] changes_file_list = glob.glob("%s/%s/*.changes" % (repo.path, packaging_dir)) - - if args.spec or not changes_file_list: - # Create .changes file with the same name as a spec - specfile = os.path.basename(guess_spec(repo.path, - packaging_dir, args.spec)[0]) - fn_changes = os.path.splitext(specfile)[0] + ".changes" - fn_changes = os.path.join(repo.path, packaging_dir, fn_changes) - else: + if changes_file_list: fn_changes = changes_file_list[0] if len(changes_file_list) > 1: log.warning("Found more than one changes files, %s is taken " % (changes_file_list[0])) - - # get the commit start from the args.since - commitid_since = get_first_commit(repo, fn_changes, args.since) - - commits = repo.get_commits(commitid_since, 'HEAD') - if not commits: - raise GbsError("Nothing found between %s and HEAD" % commitid_since) - - if args.message: - author = repo.get_author_info() - lines = ["- %s" % line for line in args.message.split(os.linesep) \ - if line.strip()] - new_entries = ["* %s %s <%s> %s" % \ - (datetime.datetime.now().strftime("%a %b %d %Y"), - author.name, author.email, - get_version(repo, commits[0]))] - new_entries.extend(lines) else: - new_entries = make_log_entries(commits, repo) + fn_changes = 'CHANGES' + + gbp_args = ['dummy argv[0]', + '--color-scheme=magenta:green:yellow:red', + '--ignore-branch', + '--changelog-revision=%(tagname)s', + '--spawn-editor=always', + '--git-author', + '--packaging-dir=%s' % packaging_dir, + '--spec-file=%s' % specfile, + '--changelog-file=%s' % fn_changes, + '--editor-cmd=%s' % get_editor_cmd(), + ] + if args.since: + gbp_args.append('--since=%s' % args.since) + if args.message: + gbp_args.append('--message=%s' % args.message) - content = get_all_entries(fn_changes, new_entries) - if edit_file(fn_changes, content): - log.info("Change log has been updated.") + ret = gbp_rpm_ch(gbp_args) + if ret: + raise GbsError("Change log has not been updated") else: - log.info("Change log has not been updated") + log.info("Change log has been updated.") diff --git a/gitbuildsys/utils.py b/gitbuildsys/utils.py index e19c951..3814038 100644 --- a/gitbuildsys/utils.py +++ b/gitbuildsys/utils.py @@ -642,13 +642,18 @@ def glob_in_rev(git_path, pattern, commit_id): return fnmatch.filter(output.splitlines(), pattern) +def get_editor_cmd(): + """Determine the preferred text editor command""" + from gitbuildsys.conf import configmgr + return configmgr.get('editor') or os.getenv('EDITOR') or 'vi' + + def edit(initial_content=None): """ Launch an editor to get input from user. Returns: content of user input. """ - from gitbuildsys.conf import configmgr - editor = configmgr.get('editor') or os.getenv('EDITOR') or 'vi' + editor = get_editor_cmd() temp = TempCopy(initial_content) subprocess.call('%s %s' % (editor, temp.name), shell=True) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index a718551..51922bb 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -26,7 +26,7 @@ import imp import datetime import time -from nose.tools import eq_, raises +from nose.tools import eq_, ok_, assert_raises, raises from gbp.git.repository import GitRepository @@ -35,6 +35,16 @@ from gitbuildsys.errors import GbsError GBS = imp.load_source("gbs", "./tools/gbs").main ENV = {} +TEST_SPEC_CONTENT=""" +Name: test +Version: 1.0 +Release: 0 +License: GPL-2.0 +Summary: Test spec file +%description +Test spec file for changelog testing +""" + def set_editor(editor): '''set editor''' os.environ['EDITOR'] = editor @@ -89,15 +99,20 @@ class TestChangelog(unittest.TestCase): # [Re]create packaging/test.spec shutil.rmtree('packaging', ignore_errors=True) os.mkdir('packaging') - open("packaging/test.spec", "w").close() + with open("packaging/test.spec", "w") as spec_fp: + spec_fp.write(TEST_SPEC_CONTENT) - set_editor("sleep 1 && touch") + set_editor("touch") def test_new_changes(self): """Test generating new .changes.""" - eq_(GBS(argv=["gbs", "changelog"]), None) + with assert_raises(GbsError): + eq_(GBS(argv=["gbs", "changelog"]), None) + ok_(not os.path.exists(self.changes)) + + eq_(GBS(argv=["gbs", "changelog", "--since=HEAD~2"]), None) eq_(open(self.changes).read(), - "* %s %s <%s> %s\n- change 3\n- change 2\n- change 1\n\n" % \ + "* %s %s <%s> %s\n- change 2\n- change 3\n\n" % \ (ENV["date"], ENV["name"], ENV["email"], ENV["commits"][0][:7])) def test_new_changes_with_content(self): @@ -116,7 +131,7 @@ class TestChangelog(unittest.TestCase): changes.write(init) eq_(GBS(argv=["gbs", "changelog"]), None) - expected = "* %s %s <%s> %s\n- change 3\n- change 2\n\n" % \ + expected = "* %s %s <%s> %s\n- change 2\n- change 3\n\n" % \ (ENV["date"], ENV["name"], ENV["email"], ENV["commits"][0][:7]) eq_(open(self.changes).read(), expected+init) @@ -132,7 +147,7 @@ class TestChangelog(unittest.TestCase): def test_not_updated(): """Test normal exit when changelog is not updated.""" set_editor("true") - eq_(GBS(argv=["gbs ", "changelog"]), None) + eq_(GBS(argv=["gbs ", "changelog", "-m", "new entry"]), None) @staticmethod @raises(GbsError)