Daniel Fütterer
28.01.21 398ff1150aa0334565b6aa614a08a910d238bfbc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/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")