kotones-auto-assistant/tools/extract_changelog.py

107 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import subprocess
import argparse
from typing import NamedTuple
from collections import defaultdict
class Commit(NamedTuple):
message: str
hash: str
def get_commit_messages():
# 获取最新的 tag
latest_tag = subprocess.check_output(['git', 'describe', '--tags', '--abbrev=0']).decode().strip()
# 获取自该 tag 以来的所有 commit message 和 hash
log = subprocess.check_output(['git', 'log', f'{latest_tag}..HEAD', '--pretty=format:%h|%s']).decode().strip()
commits = []
for line in log.split('\n'):
commit_hash, message = line.split('|', 1)
commits.append(Commit(message, commit_hash))
return commits
def categorize_commits(commits):
categories = defaultdict(lambda: defaultdict(list))
for commit in commits:
msg = commit.message
# 提取类型和范围
if ':' in msg:
prefix, content = msg.split(':', 1)
if '(' in prefix and ')' in prefix:
type_part, scope = prefix.split('(', 1)
scope = scope.rstrip(')')
else:
type_part = prefix
scope = '*'
# 分类处理
if type_part.startswith('feat'):
categories['feat'][scope].append(commit)
elif type_part.startswith('fix'):
categories['fix'][scope].append(commit)
elif type_part.startswith('refactor'):
categories['refactor'][scope].append(commit)
elif msg.startswith('docs:'):
categories['docs']['*'].append(commit)
elif msg.startswith('test:'):
categories['test']['*'].append(commit)
elif msg.startswith('chore:'):
categories['chore']['*'].append(commit)
else:
categories['other']['*'].append(commit)
return categories
def print_changelog(categories, output_file=None):
output = []
# 定义分类映射
category_map = {
'feat': '新增',
'fix': '修复',
'refactor': '重构',
'docs': '文档',
'test': '单测',
'chore': '其他',
'other': '其他'
}
# 定义范围映射
scope_map = {
'task': '脚本',
'ui': '界面',
'core': '框架',
'devtool': '开发工具',
'bootstrap': '启动器',
'*': '其他'
}
# 按指定顺序输出
for scope in scope_map.keys():
scope_output = []
for category, scopes in categories.items():
if scope in scopes and scopes[scope]:
for commit in scopes[scope]:
# 使用 commit 对象中的信息
scope_output.append(f"* [{category_map[category]}] {commit.message.split(':', 1)[1].strip()}#{commit.hash}")
if scope_output:
output.append(f"{scope_map[scope]}")
output.extend(scope_output)
output.append("")
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.write('\n'.join(output))
else:
print('\n'.join(output))
def main():
parser = argparse.ArgumentParser(description='生成更新日志')
parser.add_argument('-o', '--output', help='输出文件路径')
args = parser.parse_args()
commits = get_commit_messages()
categories = categorize_commits(commits)
print_changelog(categories, args.output)
if __name__ == '__main__':
main()