#!/usr/bin/env python3 # -*- coding: utf-8 -*- ##### To Do ##### # - handle further keywords/types other than "feat" and "fix" # - deal with parameters configuring the output (dev/usr; types, hash y/n, ...) # Refactoring: rewrite using oop (-> UML) # the processing ang recognizing of the commit components should be improved import os # a multidimensional list containing all commits separated by lines commitHistory = [] # a multidimensional list containing all commits grouped by tags taggedHistory = [] # a list of keywords used in the default conventional git (https://www.conventionalcommits.org/en/v1.0.0/) # may later get converted into a dict keywords = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "style", "test"] # get the formatted output from git log with additional delimiter for easier splitting stream = os.popen("git log --format=%B%H%n%d%n--END--") output = stream.read() output = output.split("--END--") del output[-1] # compute every commit (sepratae, delete unnecessary components, store into commitHistory) for commit in output: # seperate lines wholeCommit = commit.split("\n") commit = [x for x in wholeCommit if x] # delete unnecessary lines for i,line in enumerate(commit): if line == "": del commit[i] if len(commit[1]) == 40: # Please improve here pass elif len(commit[2]) == 40: del commit[1] else: commit[2] = commit[2].strip() # put commit into list commitHistory.append(commit) # Grouping History using tags for commit in commitHistory: # Look if commit has a tag if (len(commit) == 3) and ("tag: v" in commit[2]): taggedHistory.append([commit[2][(commit[2].rfind(": v")+3):-1],commit[0:2]]) else: # Check if latest commit has a tag if len(taggedHistory)==0: # If there is no tag, create empty string instead taggedHistory.append(["", commit]) else: taggedHistory[-1].append(commit) # Construction of the changelog-file fileTemplate = ["# Changelog"] for tag in taggedHistory: # A Dictionairy to store grouped commits commitsByType = {"Fixes":[],"Features":[]} # If latest commit has no tag: if tag[0] == "": fileTemplate.append("\n## No version number yet ") else: fileTemplate.append("\n## Version " + tag[0]) # Grouping by type "feat" and "fix" for commit in tag[1:]: old = commit[0] if commit[0].startswith(keywords[5]): # "fix" if commit[0].startswith("fix: "): new = old[(old.index(":")+2):] commit[0] = new commitsByType["Fixes"].append(commit) else: new = "**" + old[(old.index("(")+1):old.index(")")] + "**: " + old[(old.index(":")+2):] commit[0] = new commitsByType["Fixes"].append(commit) elif commit[0].startswith(keywords[4]): # "feat" if commit[0].startswith("feat: "): new = old[(old.index(":")+2):] commit[0] = new commitsByType["Features"].append(commit) else: new = "**" + old[(old.index("(")+1):old.index(")")] + "**: " + old[(old.index(":")+2):] commit[0] = new commitsByType["Features"].append(commit) # Creating grouped output if len(commitsByType["Features"]) != 0: fileTemplate.append("### Features") for feature in commitsByType["Features"]: fileTemplate.append("- " + feature[0] + " (" + commit[1][:6] + ")") if len(commitsByType["Fixes"]) != 0: fileTemplate.append("### Fixes") for fix in commitsByType["Fixes"]: fileTemplate.append("- " + fix[0] + " (" + commit[1][:6] + ")") # write into changelog with open("changelog.md", "w") as file: for line in fileTemplate: file.write(line + "\n")