Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Adam <krzmbrzl@gmail.com>2021-02-26 18:17:13 +0300
committerRobert Adam <krzmbrzl@gmail.com>2021-02-26 18:18:45 +0300
commit35b138b1557f9c29488a09322ddf7cdea7bf3d23 (patch)
tree49c1f696013a97a86a8286b0cf03c1374ca815f4 /scripts
parent384196a99f3446cff9984c873882a3eb37af0013 (diff)
MAINT: Added script to automatically generate Changelog
The script automatically parses the new merge commits between two given tags and tries its best to generate a Changelog out of it.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/commitMessage/CommitMessage.py56
-rwxr-xr-xscripts/generateChangelog.py141
2 files changed, 197 insertions, 0 deletions
diff --git a/scripts/commitMessage/CommitMessage.py b/scripts/commitMessage/CommitMessage.py
new file mode 100644
index 000000000..a9a778ed9
--- /dev/null
+++ b/scripts/commitMessage/CommitMessage.py
@@ -0,0 +1,56 @@
+import re
+
+class CommitFormatError(Exception):
+
+ def __init__(self, msg):
+ Exception(msg)
+
+class CommitMessage:
+ knownTypes = ["BREAK", "FEAT", "FIX", "FORMAT", "DOCS", "TEST", "MAINT", "CI", "REFAC", "BUILD", "TRANSLATION"]
+
+ def __init__(self, commitString):
+ lines = commitString.strip().split("\n")
+
+ if len(lines) < 1 or lines[0].strip() == "":
+ raise CommitFormatError("Invalid commit content")
+
+ subjectPattern = re.compile("^([A-Z\-_/]+)(?:\(([0-9a-zA-Z\-_, ]+)\))?:\s*(.+)$")
+
+ match = re.match(subjectPattern, lines[0])
+
+ if not match:
+ raise CommitFormatError("The provided commit's subject line does not follow the required pattern")
+
+ types = match.group(1).split("/") if not match.group(1) is None else []
+ scopes = match.group(2).split(",") if not match.group(2) is None else []
+ summary = match.group(3).strip() if not match.group(3) is None else ""
+
+ if len(types) == 0:
+ raise CommitFormatError("Missing type")
+
+ if len(summary) == 0:
+ raise CommitFormatError("Missing summary")
+
+ self.m_summary = summary
+
+ types = [x.strip() for x in types]
+ scopes = [x.strip().lower() for x in scopes]
+
+ for currentType in types:
+ if currentType == "":
+ raise CommitFormatError("Subsequent \"/\" not allowed for separating types")
+
+ if not currentType in self.knownTypes:
+ raise CommitFormatError("Unknown type \"%s\" (or incorrect spelling)" % currentType)
+
+ self.m_types = types
+
+ for currentScope in scopes:
+ if currentScope == "":
+ raise CommitFormatError("Empty scope not allowed")
+
+ self.m_scopes = scopes
+
+ self.m_body = "\n".join(lines[1 : ]) if len(lines) > 1 else ""
+
+
diff --git a/scripts/generateChangelog.py b/scripts/generateChangelog.py
new file mode 100755
index 000000000..f6cf1c03c
--- /dev/null
+++ b/scripts/generateChangelog.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 The Mumble Developers. All rights reserved.
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file at the root of the
+# Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+import argparse
+import platform
+import subprocess
+
+from commitMessage.CommitMessage import CommitMessage, CommitFormatError
+
+def cmd(args):
+ shell = platform.system() == 'Windows'
+ p = subprocess.Popen(args, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ raise Exception('cmd(): {0} failed with status {1}: {2}'.format(args, p.returncode, stderr))
+ return stdout.decode('utf-8')
+
+def isRelevantCommit(commitLine):
+ if commitLine.strip() == "":
+ return False
+
+ components = commitLine.split()
+
+ if len(components) < 2:
+ return False
+
+ # First component is commit hash
+ # We only consider merge commits to be relevant
+ return components[1].lower() == "merge"
+
+def formatChangeLine(line, prNumber, target):
+ if target == "github":
+ return "- {} (#{})".format(line, prNumber)
+ elif target == "website":
+ return "- {} ({{{{< issue {} >}}}})".format(line, prNumber)
+ else:
+ return "- {} (https://github.com/mumble-voip/mumble/pull/{})".format(line, prNumber)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("FROM_TAG", help="Tag or commit to start the diff from")
+ parser.add_argument("TO_TAG", help="Tag or commit to end the diff at")
+ parser.add_argument("--target", choices=["github", "website", "other"], help="Generate the Changelog in a format suitable for this target",
+ default="other")
+ args = parser.parse_args()
+
+ commits = cmd(["git", "log" ,"--format=oneline", "--date=short", "{}..{}".format(args.FROM_TAG, args.TO_TAG)]).split("\n")
+ commits = list(filter(isRelevantCommit, commits))
+
+ serverChanges = []
+ clientChanges = []
+ sharedChanges = []
+ miscChanges = []
+
+ skipTypes = set(["FORMAT", "DOCS", "TEST", "MAINT", "CI", "REFAC", "BUILD", "TRANSLATION"])
+
+ for commitLine in commits:
+ parts = commitLine.split(maxsplit=1)
+ commitHash = parts[0]
+ commitTitle = parts[1]
+
+ assert ":" in commitTitle
+ assert "#" in commitTitle
+
+ prTagStart = commitTitle.find("#")
+ prTagEnd = commitTitle.find(":")
+ assert prTagStart + 1 < prTagEnd
+
+ # Extract PR number
+ prNumber = commitTitle[prTagStart + 1 : prTagEnd]
+ # Cut out PR information from commit title
+ commitTitle = commitTitle[prTagEnd + 1 : ].strip()
+
+ try:
+ commit = CommitMessage(commitTitle)
+
+ if len(set(commit.m_types) & skipTypes) > 0:
+ # We don't list these changes in the changelog
+ continue
+
+ targetGroups = []
+ if "client" in commit.m_scopes:
+ targetGroups.append(clientChanges)
+ if "server" in commit.m_scopes:
+ targetGroups.append(serverChanges)
+ if "shared" in commit.m_scopes:
+ targetGroups.append(sharedChanges)
+ if len(targetGroups) == 0:
+ targetGroups.append(miscChanges)
+
+ prefix = ""
+ if "FEAT" in commit.m_types:
+ prefix = "Added: "
+ elif "FIX" in commit.m_types:
+ prefix = "Fixed: "
+ else:
+ prefix = "Unknown: "
+
+ for currentTarget in targetGroups:
+ currentTarget.append(formatChangeLine(prefix + commit.m_summary, prNumber, args.target))
+ except CommitFormatError:
+ # We can't classify the change -> assume misc
+ miscChanges.append(formatChangeLine("Unknown: " + commitTitle, prNumber, args.target))
+
+
+ if len(clientChanges) > 0:
+ print("### Client")
+ print()
+ print("\n".join(sorted(clientChanges)))
+ print()
+ print()
+
+ if len(serverChanges) > 0:
+ print("### Server")
+ print()
+ print("\n".join(sorted(serverChanges)))
+ print()
+ print()
+
+ if len(sharedChanges) > 0:
+ print("### Both")
+ print()
+ print("\n".join(sorted(sharedChanges)))
+ print()
+ print()
+
+ if len(miscChanges):
+ print("### Miscellaneous")
+ print()
+ print("\n".join(sorted(miscChanges)))
+ print()
+
+
+
+if __name__ == "__main__":
+ main()