forked from Mudlet/Mudlet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate-ptb-changelog.lua
executable file
·142 lines (115 loc) · 4.26 KB
/
generate-ptb-changelog.lua
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
-- for appveyor
mingw_base_dir = os.getenv("MINGW_BASE_DIR")
if mingw_base_dir then
package.path = package.path .. ";"..mingw_base_dir.."/share/lua/5.1/?.lua"
end
local argparse = require "argparse"
local lunajson = require "lunajson"
-- don't load all of LuaGlobal, as that requires yajl installed
local github_workspace = os.getenv("GITHUB_WORKSPACE")
if github_workspace then
-- the script struggles to load the load files relatively in CI
loadfile(github_workspace.. "/src/mudlet-lua/lua/StringUtils.lua")()
loadfile(github_workspace.."/src/mudlet-lua/lua/TableUtils.lua")()
else
loadfile("../src/mudlet-lua/lua/StringUtils.lua")()
loadfile("../src/mudlet-lua/lua/TableUtils.lua")()
end
local parser = argparse("generate-ptb-changelog.lua", "Generate a changelog from the HEAD until the most recent published commit.")
parser:option("-r --releasefile", "Downloaded DBLSQD release feed file")
local args = parser:parse()
local MAX_COMMITS_PER_CHANGELOG = 100
-- Basic algorithm is as follows:
-- retrieve last X commit hashes from current branch
-- retrieve list of releases and their hashes
-- go through the list collect hashes not present in releases
-- then get the changelog for the range of hashes
-- html-ize and return the results.
-- credit: https://stackoverflow.com/a/326715/72944
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end
function read_file(path)
local file = io.open(path, "rb")
if not file then return nil end
local content = file:read "*a"
file:close()
return content
end
function extract_released_sha1s(input)
local decoded = lunajson.decode(input)
local t = {}
for _, release in ipairs(decoded.releases) do
t[#t+1] = release.version:match(".+%-(.-)$")
end
return t
end
function extract_historical_sha1s()
local history, command
if github_workspace then
command = string.format("git log --pretty=%%H -n %d %s", MAX_COMMITS_PER_CHANGELOG, os.getenv("GITHUB_SHA"))
history = string.split(os.capture(command))
else
command = "git log --pretty=%H -n "..MAX_COMMITS_PER_CHANGELOG
history = string.split(os.capture(command))
end
local t = {}
for _, sha1 in ipairs(history) do
t[#t+1] = sha1:match("^(........)")
end
return t
end
function get_releases(location)
return read_file(location)
end
-- returns a list of commits that have been added since the last release
function scan_commits(historical_commits, released_commits)
local commits_added_since = {}
local released_commits_length = #released_commits[1]
for i, commit in ipairs(historical_commits) do historical_commits[i] = string.cut(commit, released_commits_length) end
for i, v in ipairs(historical_commits) do
if table.contains(released_commits, v) then
commits_added_since[#commits_added_since + 1] = v
return commits_added_since
end
commits_added_since[#commits_added_since + 1] = v
end
print("(hit the "..MAX_COMMITS_PER_CHANGELOG.." commit limit - couldn't find the latest published PTB release)")
return {}
end
function get_changelog(commit1, commit2)
return os.capture(string.format("git log --pretty=%%s %s..%s", commit1, commit2), true):trim()
end
function escape_for_html(text)
local escapes = {
["&"] = "&",
["<"] = "<",
[">"] = ">",
['"'] = """,
["'"] = "'"
}
return text:gsub(".", escapes)
end
function convert_to_html(text)
local t = {}
text = text.."\n"
for s in string.gmatch(text, "(.-)\n") do
s = escape_for_html(s)
s = s:gsub("%(#(.-)%)", [[<a href="https://github.com/Mudlet/Mudlet/pull/%1">(#%1)</a>]])
t[#t+1] = string.format("<p>%s</p>", s)
end
return table.concat(t, "\n")
end
local historical_commits = extract_historical_sha1s()
local released_commits = extract_released_sha1s(get_releases(args.releasefile))
local unpublished_commits = scan_commits(historical_commits, released_commits)
if table.is_empty(unpublished_commits) then print("(changelog couldn't be generated)") os.exit() end
local changelog = get_changelog(unpublished_commits[#unpublished_commits], unpublished_commits[1])
print(convert_to_html(changelog))