-
Notifications
You must be signed in to change notification settings - Fork 48
/
generate-changelog.py
executable file
·85 lines (67 loc) · 2.7 KB
/
generate-changelog.py
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
#!/usr/bin/env python3
import argparse
import locale
import os.path
import subprocess
import sys
import re
locale.setlocale(locale.LC_ALL, "en_US.utf-8")
parser = argparse.ArgumentParser(
description="Generate a changelog for an engineering build or RC of ARC GNU Toolchain.")
parser.add_argument("--src-dir", required=True,
help="Root of toolchain source directories.")
parser.add_argument("--tag", required=True,
help="Git tag of a new build.")
parser.add_argument("--max-commits", default=50, type=int,
help="Maximum number of commits printed for one project.")
args = parser.parse_args()
repos = ["binutils", "gcc", "gdb", "newlib", "toolchain" ]
new_tag = args.tag
# Build an old tag. RC and eng build has different formats.
build_num_m = re.search("\D*(\d+)$", new_tag)
build_num = int(build_num_m.group(1))
old_tag = new_tag[0:build_num_m.start(1)]
if old_tag.endswith("-eng"):
old_tag += "{0:03}".format(build_num - 1)
else:
old_tag += str(build_num - 1)
git="git"
def git_command(*args):
a = [git, git_dir]
a.extend(args)
return subprocess.run(a, check=True, stdout=subprocess.PIPE, universal_newlines=True).stdout
for repo in repos:
git_dir = "--git-dir=" + os.path.join(args.src_dir, repo, ".git")
# For GDB tag is different.
new_tag_effective = new_tag if repo != "gdb" else new_tag + "-gdb"
old_tag_effective = old_tag if repo != "gdb" else old_tag + "-gdb"
# First get commit ids. Use ^{} to get an ID of an actual commit, not an ID of a tag.
new_commit_id = git_command("rev-parse", new_tag_effective + "^{}")
try:
old_commit_id = git_command("rev-parse", old_tag_effective + "^{}")
except:
print("Cannot get previous commit id. Most likely {} is not exist. Skipping changelog generation."
.format(old_tag_effective))
continue
# Same? Nothing to do.
if old_commit_id == new_commit_id:
continue
print()
print(repo)
# Underline the header.
print('-' * max(len(repo), 7))
# Find the common base commit.
merge_base_id = git_command("merge-base", new_tag_effective, old_tag_effective)
# If it is the same as "old" then history is linear, no rebases, just use
# normal `git log --oneline`.
if merge_base_id == old_commit_id:
log_cmd = ["log", "--oneline", "{0}..{1}".format(old_tag_effective, new_tag_effective)]
else:
log_cmd = ["show-branch", old_tag_effective, new_tag_effective]
out = git_command(*log_cmd).splitlines()
if len(out) < args.max_commits:
print("\n".join(out))
else:
print("!!!Output is too long and has been truncated!!!")
print("\n".join(out[0:args.max_commits]))
# vim: expandtab