chore: 优化 Changelog 生成器

This commit is contained in:
zzyyyl
2023-03-07 14:29:00 +08:00
parent fda8fea4ab
commit f24ded005c

View File

@@ -13,75 +13,27 @@ contributors = {
"@[Hao Guan]": "@hguandl",
}
# 从哪个 tag 开始
latest = os.popen("git describe --abbrev=0 --tags").read()[:-1]
print("From:", latest, "\n")
# 输出一张好看的 git log 图到控制台
git_pretty_command = rf'git log {latest}..HEAD --pretty=format:"%C(yellow)%d%Creset %s %C(bold blue)@%an%Creset (%Cgreen%h%Creset)" --graph'
os.system(git_pretty_command)
# 获取详细的 git log 信息
git_command = rf'git log {latest}..HEAD --pretty=raw'
with os.popen(git_command) as fp: bf = fp._stream.buffer.read()
try: gitlogs = bf.decode().strip()
except: gitlogs = bf.decode("gbk").strip()
current_commit = None
current_commit_status = ""
raw_commits_info = {}
for line in gitlogs.split("\n"):
line = re.sub(r"^ *", "", line)
if line.startswith("commit "):
current_commit = line[7:]
current_commit_status = ""
raw_commits_info[current_commit] = {}
if current_commit == None:
continue
if line == "":
continue
elif line.startswith("parent "):
if "parent" not in raw_commits_info[current_commit]:
raw_commits_info[current_commit]["parent"] = []
raw_commits_info[current_commit]["parent"].append(line[7:])
elif line.startswith("author "):
raw_commits_info[current_commit].update({ "author": line[7:].split(' <', 1)[0] })
elif line.startswith("committer "):
raw_commits_info[current_commit].update({ "committer": line[10:].split(' <', 1)[0] })
elif line.startswith("gpgsig"):
current_commit_status = "gpgsig"
elif line.find("-----END PGP SIGNATURE-----") != -1:
current_commit_status = ""
elif line.startswith("commit "):
pass
elif line.startswith("tree "):
pass
elif current_commit_status == "":
if "message" in raw_commits_info[current_commit] and not raw_commits_info[current_commit]["message"].startswith("Merge"):
continue
raw_commits_info[current_commit]["message"] = line
commits = {}
def search_commits(commit_hash: str, to):
# dfs 建树Merge commit 是非叶子节点
def build_commits_tree(commit_hash: str):
res = {}
if commit_hash not in raw_commits_info:
return
return res
raw_commit_info = raw_commits_info[commit_hash]
if "visited" in raw_commit_info:
return
return res
raw_commit_info.update({"visited": True})
commit_key = raw_commit_info["message"] + f" @[{raw_commit_info['author']}]"
to[commit_key] = {}
search_commits(raw_commit_info["parent"][0], to)
commit_key = raw_commit_info["message"] + f" ({raw_commit_info['hash']})" + f" @[{raw_commit_info['author']}]"
res[commit_key] = {}
res.update(build_commits_tree(raw_commit_info["parent"][0]))
if len(raw_commit_info["parent"]) == 2:
search_commits(raw_commit_info["parent"][1], to[commit_key])
search_commits([x for x in raw_commits_info.keys()][0], commits)
# print(json.dumps(commits, ensure_ascii=False, indent=2))
# exit(0)
if commit_key.startswith("Release"):
# 避免合并之后只有一个 Release 主 commit
res.update(build_commits_tree(raw_commit_info["parent"][1]))
else:
res[commit_key].update(build_commits_tree(raw_commit_info["parent"][1]))
if commit_key.startswith("Merge branch") and not res[commit_key]:
res.pop(commit_key)
return res
def print_commits(commits: dict, indent: str = "", need_sort: bool = True) -> (str, list):
if not commits: return ("", [])
@@ -98,18 +50,18 @@ def print_commits(commits: dict, indent: str = "", need_sort: bool = True) -> (s
for x in commits.keys():
if False:
pass
elif x.find("新增") != -1:
sorted_commits["feat"][x] = commits[x]
elif x.find("改进") != -1 or x.find("更新") != -1 or x.find("优化") != -1 or x.find("重构") != -1:
sorted_commits["perf"][x] = commits[x]
elif x.find("修复") != -1:
sorted_commits["fix"][x] = commits[x]
elif x.startswith("feat"):
sorted_commits["feat"][x] = commits[x]
elif x.startswith("perf"):
sorted_commits["perf"][x] = commits[x]
elif x.startswith("fix"):
sorted_commits["fix"][x] = commits[x]
elif x.find("新增") != -1:
sorted_commits["feat"][x] = commits[x]
elif x.find("改进") != -1 or x.find("优化") != -1:
sorted_commits["perf"][x] = commits[x]
elif x.find("修复") != -1:
sorted_commits["fix"][x] = commits[x]
else:
sorted_commits["other"][x] = commits[x]
@@ -173,8 +125,31 @@ def print_commits(commits: dict, indent: str = "", need_sort: bool = True) -> (s
return ret_message, ret_contributor
res = print_commits(commits)
nightly = os.popen("git describe --tags").read()[:-1]
if __name__ == "__main__":
# 从哪个 tag 开始
latest = os.popen("git describe --abbrev=0 --tags").read()[:-1]
latest = "v4.12.0-beta.1"
nightly = os.popen("git describe --tags").read()[:-1]
print("From:", latest, ", To:", nightly, "\n")
with open("../changelog.md", "w", encoding="utf8") as f:
f.write("## " + nightly + "\n" + res[0])
# 输出一张好看的 git log 图到控制台
git_pretty_command = rf'git log {latest}..HEAD --pretty=format:"%C(yellow)%d%Creset %s %C(bold blue)@%an%Creset (%Cgreen%h%Creset)" --graph'
os.system(git_pretty_command)
print()
# 获取详细的 git log 信息
git_command = rf'git log {latest}..HEAD --pretty=format:"\"%H\":{{\"hash\":\"%h\",\"author\":\"%aN\",\"committer\":\"%cN\",\"message\":\"%s\",\"parent\":\"%P\"}},"'
with os.popen(git_command) as fp: bf = fp._stream.buffer.read()
try: gitlogs = bf.decode().strip()
except: gitlogs = bf.decode("gbk").strip()
gitlogs = "{" + gitlogs[:-1] + "}"
raw_commits_info = json.loads(gitlogs)
for x, y in raw_commits_info.items():
y["parent"] = y["parent"].split()
# print(json.dumps(raw_commits_info, ensure_ascii=False, indent=2))
res = print_commits(build_commits_tree([x for x in raw_commits_info.keys()][0]))
with open("../changelog.md", "w", encoding="utf8") as f:
f.write("## " + nightly + "\n" + res[0])