From b07d2e00d40692f9076e65cfe41140d4515b7b32 Mon Sep 17 00:00:00 2001 From: Daniel Fütterer <df89@outlook.com> Date: Tue, 27 Apr 2021 14:12:29 +0200 Subject: [PATCH] feat: Added version with scopes --- oop_changelog_scope.py | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 220 insertions(+), 0 deletions(-) diff --git a/oop_changelog_scope.py b/oop_changelog_scope.py new file mode 100644 index 0000000..bd28462 --- /dev/null +++ b/oop_changelog_scope.py @@ -0,0 +1,220 @@ +import os.path + +## To Do +# - Breaking Changes +# - Merge Commits +# - Error Handling + +def getSeparatedGitLog(repo): + try: + stream = os.popen("git -C {} log --format=%B--SEP--%H--SEP--%d--END--".format(repo)) + except: + raise ValueError("Not a valid git-repository!") + else: + gitLog = stream.read() + commitList = gitLog.split("--END--") + del commitList[-1] + return commitList + + +class RawCommit: + def __init__(self, completeCommit): + self.raw = completeCommit.split("--SEP--") + self.body = self.raw[0].strip() + self.hash = self.raw[1].strip() + self.tag = self.raw[2].strip() + + +class CommitBody: + commitTypes = ("build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "style", "test") + def __init__(self, completeMessage): + self.completeMessage = completeMessage + #self.subject = None + #self.body = None + #self.scope = None + #self.commitType = None + + self.setSubjectAndBody() + self.setScope() + self.setCommitType() + + def setSubjectAndBody(self): + try: + subStart = self.completeMessage.index(": ")+2 + except: + try: + subStart = self.completeMessage.index("\n") + except: + subStart = 0 + try: + subEnd = self.completeMessage.index("\n") + except: + self.subject = self.completeMessage[subStart:] + self.body = None + else: + self.subject = self.completeMessage[subStart:subEnd] + self.body = self.completeMessage[subEnd:].strip() + + def setScope(self): + try: + start = self.completeMessage.index("(")+1 + end = self.completeMessage.index(")") + except: + self.scope = None + else: + self.scope = self.completeMessage[start:end].strip().lower() + + def setCommitType(self): + for commitType in self.commitTypes: + if (self.completeMessage.startswith((commitType + ": "))) or (self.completeMessage.startswith((commitType + "("))) or (self.completeMessage.startswith((commitType + " ("))): + self.commitType = commitType + break + else: + self.commitType = "nonconform" + + def getCommitMessageWithType(self): + return self.commitType + ": " + self.subject + +class Scope: + def __init__(self, name): + self.name = name.strip().lower() + + @staticmethod + def createScope(name): + return Scope(name) + +class CommitTag: + def __init__(self, completeTag): + if not ("tag: " in completeTag): + self.completeTag = None + self.tagAsString = None + self.major = None + self.minor = None + self.bugfix = None + else: + self.completeTag = completeTag + self.setTagAsString() + self.setMajorMinorBugfix() + + def setTagAsString(self): + try: ## this one is temporary + self.tagAsString = self.completeTag[(self.completeTag.rindex(": v.")+4):-1] + except: + try: + self.tagAsString = self.completeTag[(self.completeTag.rindex(": v")+3):-1] + except: + self.tagAsString = self.completeTag[(self.completeTag.rindex(": ")+2):-1] + + def setMajorMinorBugfix(self): + versionList = self.tagAsString.split(".") + self.major = versionList[0] + self.minor = versionList[1] + self.bugfix = versionList[2] + + @staticmethod + def getUpdateType(newTag, previousTag): + if newTag.major > previousTag.major: + return "major" + elif newTag.minor > previousTag.minor: + return "minor" + elif newTag.bugfix > previousTag.bugfix: + return "bugfix" + + +class Commit: + def __init__(self, rawCommit): + self.body = CommitBody(rawCommit.body) + self.tag = CommitTag(rawCommit.tag) + self.hash = rawCommit.hash + + def appendShortHash(self): + return " (" + self.hash[:6] + ")" + + + +#### Main #### + +pathToRepo = "/Users/daniel/Developer/Repos/HfM/schumacher/Prisma-Binauralize" +#pathToRepo = "/Users/daniel/Desktop/testrepo" + +commitList = getSeparatedGitLog(pathToRepo) + +# Create a list of commits +commitHistory = [] +for commit in commitList: + commitHistory.append(Commit(RawCommit(commit))) + +# Create a two-dimensional list by tags: [[tag, [commits]],[tag, [commits]],...] +taggedHistory = [] +for commit in commitHistory: + if commit.tag.tagAsString: + taggedHistory.append([commit.tag, commit]) + else: + if len(taggedHistory) == 0: + taggedHistory.append([None, commit]) + else: + taggedHistory[-1].append(commit) + + +# Construction of the changelog-file +fileTemplate = ["# Changelog"] +for tag in taggedHistory: + # If latest commit has no tag: + if not tag[0]: + fileTemplate.append("\n## Without version number") + else: + fileTemplate.append("\n## Version " + tag[0].tagAsString) + + + # Grouping by Type + commitsByType = {"Other":[], "Features":[], "Fixes":[]} + nonconformCommits = [] + for commit in tag[1:]: + if commit.body.commitType == CommitBody.commitTypes[5]: # fix + commitsByType["Fixes"].append(commit) + elif commit.body.commitType == CommitBody.commitTypes[4]: # feat + commitsByType["Features"].append(commit) + elif commit.body.commitType == "nonconform": + nonconformCommits.append(commit) + else: + commitsByType["Other"].append(commit) + + # Sub-Grouping by Scopes within Types + while len(commitsByType) > 0: + commitsByScope = {} + commitType, commits = commitsByType.popitem() + if len(commits) == 0: + continue + + for commit in commits: + if commit.body.scope == None: + if "no scope" not in commitsByScope: + commitsByScope["no scope"] = [commit] + else: + commitsByScope["no scope"].append(commit) + elif commit.body.scope in commitsByScope: + commitsByScope[commit.body.scope].append(commit) + else: + commitsByScope[commit.body.scope] = [commit] + + fileTemplate.append("\n### " + str(commitType)) + while len(commitsByScope) > 0: + scope, commits = commitsByScope.popitem() + fileTemplate.append("- *" + str(scope) + "*") + for commit in commits: + if commitType == "Other": + fileTemplate.append(" - (" + commit.body.commitType + ") " + commit.body.subject + commit.appendShortHash()) + else: + fileTemplate.append(" - " + commit.body.subject + commit.appendShortHash()) + + # nonconform commits + if len(nonconformCommits) > 0: + fileTemplate.append("\n### Non-conform commits") + for commit in nonconformCommits: + fileTemplate.append("- " + commit.body.subject + commit.appendShortHash()) + + +# write into changelog +with open(pathToRepo + "/changelog.md", "w") as file: + for line in fileTemplate: + file.write(line + "\n") \ No newline at end of file -- Gitblit v1.9.1