df89
10.10.21 c4d692c98f3e06d39cf80bf8fa2035c2e398646b
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
import os.path
import sys
 
from functions import getCommitList
from rawcommit import RawCommit
from commit import Commit
from scope import Scope
from commitBody import CommitBody
 
 
# Compute user input of repository path via console
inputPath = input("Please enter the base path of the repository: ").strip()
userDecision = input("Should the generated changelog be stored in another location (y/n)? ").lower().strip()
if userDecision == "y":
    outputPath = input("Please enter the output path: ").strip()
elif userDecision == "n":
    print("The changelog will be stored in the same location as the repository.")
    outputPath = inputPath
else:
    print("invalid input")
    sys.exit(1)
 
 
# create a list of separate commits in chronological order (new to old)
commitHistory = getCommitList(inputPath)
 
 
# 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
    featType = ["Features"]
    fixType = ["Fixes"]
    otherType = ["Other"]
    nonconformCommits = []
    
    for commit in tag[1:]:
        if commit.body.commitType == CommitBody.commitTypes[5]: # fix
            fixType.append(commit)
        elif commit.body.commitType == CommitBody.commitTypes[4]: # feat
            featType.append(commit)
        elif commit.body.commitType == "nonconform":
            nonconformCommits.append(commit)
        else:
            otherType.append(commit)
 
    ## Sub-Grouping by Scopes within Types    
    commitlistByType = [featType, fixType, otherType]
    for commitsByType in commitlistByType:
        if len(commitsByType) == 1:
            continue
        commitlistByScope = {}
        noScope = []
        for commit in commitsByType:
            if type(commit) == str:
                continue
            if commit.body.scope == None:
                noScope.append(commit)
            elif commit.body.scope in commitlistByScope:
                commitlistByScope[commit.body.scope].append(commit)
            else:
                commitlistByScope[commit.body.scope] = [commit]
        
        fileTemplate.append("\n### " + commitsByType[0])
        while len(commitlistByScope) > 0:
            scope, commits = commitlistByScope.popitem()
            fileTemplate.append("- *" + str(scope) + "*")
            for commit in commits:
                if commitsByType[0] == "Other":
                    fileTemplate.append("    - (" + commit.body.commitType + ") " + commit.body.subject + commit.appendShortHash())
                else:
                    fileTemplate.append("    - " + commit.body.subject + commit.appendShortHash())
        if len(noScope) > 0:
            fileTemplate.append("- *no scope*")
        for commit in noScope:
            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.md file
with open(outputPath + "/changelog.md", "w") as file:
    for line in fileTemplate:
        file.write(line + "\n")