-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchangelog.py
159 lines (118 loc) · 3.67 KB
/
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Requires python3 to work since, python 3< does not implement %z.
import sys
import os
import json
from datetime import datetime
import pytz
from subprocess import Popen, PIPE, STDOUT
class Version(object):
def __init__(self, version):
v = version
if v.startswith('v'):
v = v[1:].split('\n')[0]
fix = v.split('.')
self.major = int(fix[0])
self.minor = int(fix[1])
self.patch = int(fix[2])
self.build = None
self.tip = False
def __str__(self):
return self.__repr__()
def __repr__(self):
return str(self.major) + "." + str(self.minor) + "." + str(self.patch)
class Changelog(object):
def __init__(self, info):
a, b, log = info
self.log = log
self.a = a
self.b = b
def log_in_between_versions(self):
hash = self.log.split(' ')[0]
if zeroversion(self.a):
return ""
date_time = git_log([str(self.a), "-1", '--format="%ad"']).split('\n')[0]
if date_time is not '':
dt = datetime.strptime(date_time, '%a %b %d %H:%M:%S %Y %z')
else:
dt = datetime.now()
dt = dt.strftime('%a, %d %b %Y %H:%M:%S')
log = str(self.a) + " - " + dt + " UTC\n"
log = log + ("-" * (len(log) - 1)) + "\n\n"
actual_log = self.log.splitlines()
if len(actual_log) == 1:
entries = "-\n\n"
else:
entries = "\n".join(map(url_entry, actual_log[1:])) + "\n\n"
log = log + entries
return log
def __str__(self):
return self.__repr__(self)
def __repr__(self):
return "Changelog: " + self.log
def url_entry(entry):
log = entry.split(' ')
hash = log[0]
log = ' '.join(log[1:])
return "- [%s](../../commit/%s) %s" % (hash, hash, log)
def zeroversion(v):
return v.major == 0 and v.minor == 0 and v.patch == 0
class compareversions(object):
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
if self.obj.major < other.obj.major:
return True
if self.obj.minor < other.obj.minor:
return True
if self.obj.patch < other.obj.patch:
return True
return False
def git_exec(args):
p = Popen(" ".join(["git"] + args), shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
return out.decode('utf-8')
def git_log(args):
return git_exec(["log"] + args)
def adjacents(ls, f, res):
if len(ls) == 0:
return res
first = ls[0]
if len(ls) == 1:
next = None
else:
next = ls[1]
res.append(f(first, next))
return adjacents(ls[1:], f, res)
def logs_between(a, b):
v = a
if b is None:
_ = str(a)
else:
if a.tip:
a = "HEAD"
else:
a = str(a)
_ = str(b) + ".." + a
return (v, b, git_log(["--format='%h %s'", _]))
def changelog(with_versions):
process = with_versions
versions = []
generate_all = len(with_versions) == 0
if generate_all:
lines = git_exec(["tag", "-l"])
process = lines.splitlines()
for item in process:
versions.append(Version(item))
versions = sorted(versions, key=compareversions, reverse=True)
if generate_all:
vs = map(Changelog, adjacents(versions, logs_between, []))
else:
versions[0].tip = True
vs = map(Changelog, [logs_between(versions[0], versions[1])])
return [v.log_in_between_versions() for v in vs]
if __name__ == "__main__":
args = sys.argv[1:]
for_version=[]
if len(args) > 0:
for_version = list(args)
print("\n".join(changelog(for_version)))