-
Thomas Woerner authored
The --tag TAG option is now printing the changes for the given TAG and not since the given tag. The new option --galaxy is printing the changelog since the latest tag and also for the latest tag. These changes are simplifying the generation of the changelog file that is needed to pass the tests for galaxy and AutomationHub collections.
Thomas Woerner authoredThe --tag TAG option is now printing the changes for the given TAG and not since the given tag. The new option --galaxy is printing the changelog since the latest tag and also for the latest tag. These changes are simplifying the generation of the changelog file that is needed to pass the tests for galaxy and AutomationHub collections.
To find the state of this project's repository at the time of any of these versions, check out the tags.
changelog 5.20 KiB
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Authors:
# Thomas Woerner <twoerner@redhat.com>
#
# Copyright (C) 2020 Red Hat
# see file 'COPYING' for use and warranty information
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
import sys
import argparse
import subprocess
class Ref:
def __init__(self, commit):
self.commit = commit
def store(commits, prs, authors, commit, author, merge, msg):
if commit is not None:
if msg[0].startswith("Merge pull request #"):
pr_ref = int(msg[0].split()[3][1:])
if len(msg) > 1:
prs[pr_ref] = msg[1].strip()
else:
prs[pr_ref] = Ref(merge)
else:
commits[commit] = msg[0].strip()
authors.setdefault(author, []).append(commit)
def get_commit(commits, commit):
_commits = [value for key, value in commits.items()
if key.startswith(commit)]
if len(_commits) == 1:
return _commits[0]
return commit
def get_output(command):
try:
ret = subprocess.check_output(command, shell=True)
ret = ret.decode("utf-8").strip()
except subprocess.CalledProcessError:
print("Command '%s' failed" % command)
sys.exit(1)
return ret
def changelog(tag):
prev_tag = None
if tag is not None and tag != "":
prev_tag = get_output(
"git describe --tag --abbrev=0 --always '%s^'" % tag)
else:
tag = get_output("git describe --tags --abbrev=0 "
"$(git rev-list --tags --max-count=1)")
version = tag[1:]
if prev_tag is not None:
command = ["git", "log", "%s..%s" % (prev_tag, tag)]
else:
command = ["git", "log", "%s.." % tag]
process = subprocess.run(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if process.returncode != 0:
print("git log failed: %s" %
process.stderr.decode("utf8").split("\n")[0])
sys.exit(1)
lines = process.stdout.decode("utf-8").split("\n")
commits = {}
prs = {}
authors = {}
commit = None
author = None
merge = None
msg = None
for line in lines:
line = line.rstrip()
if line.startswith("commit "):
store(commits, prs, authors, commit, author, merge, msg)
author = None
msg = []
commit = line[7:]
elif line.startswith(" "):
msg.append(line[4:])
else:
try:
key, value = line.split(":", 1)
if key == "Author":
author = value.split("<")[0].strip()
elif key == "Merge":
merge = value.split()[1].strip()
# Ignore Date, ..
except ValueError:
pass
# Add final commit
if commit:
store(commits, prs, authors, commit, author, merge, msg)
if prev_tag is not None:
line = "Changes for %s since %s" % (version, prev_tag[1:])
else:
line = "Changes since %s" % version
print("%s" % line)
print("-" * len(line))
print()
prs_sorted = sorted(prs.keys(), reverse=True)
for pr_ref in prs_sorted:
if isinstance(prs[pr_ref], Ref):
msg = get_commit(commits, prs[pr_ref].commit)
else:
msg = prs[pr_ref]
print(" - %s (#%d)" % (msg, pr_ref))
print()
if prev_tag is not None:
line = "Detailed changelog for %s since %s by author" % (version,
prev_tag[1:])
else:
line = "Detailed changelog since %s by author" % version
print("%s" % line)
print("-" * len(line))
print(" %d authors, %d commits" % (len(authors), len(commits)))
print()
authors_sorted = sorted(authors.keys())
for author in authors_sorted:
print("%s (%d)\n" % (author, len(authors[author])))
for commit in authors[author]:
print(" - %s" % commits[commit])
print()
parser = argparse.ArgumentParser(usage="Usage: changelog [options]")
parser.add_argument("--tag", dest="tag", help="git tag")
parser.add_argument("--galaxy", dest="galaxy", action="store_true",
help="Create changelog for galaxy")
options, args = parser.parse_known_args()
if len(args) != 0:
parser.print_help()
sys.exit(1)
if options.galaxy:
# Get latest tag
tag = get_output("git describe --tag --abbrev=0")
# get number of commits since latest tag
count = get_output("git rev-list '%s'.. --count" % tag)
if count != "0":
changelog(None)
changelog(tag)
else:
changelog(options.tag)