-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-changelog.rb
109 lines (88 loc) · 3.29 KB
/
build-changelog.rb
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
class Commit
attr_accessor :message, :date, :version, :title, :hash, :author, :body
def to_json(*a)
{
"title" => title,
"message" => message,
"date" => date,
"hash" => hash,
"version" => version
}.to_json(*a)
end
end
class Version
# versions are in the form XX.y (major.minor)
# they can also have a channel (alpha, beta, rc) and a channel number (optional)
# examples: 18.1, 18.0 RC1, 19.0 alpha 2, 20.1 beta2
# if no channel is mentioned, it's assumed to be RTW
attr_accessor :major, :minor, :channel, :channel_number
def to_json(*a)
{
"major" => major,
"minor" => minor,
"channel" => channel,
"channel_number" => channel_number
}.to_json(*a)
end
end
def log(msg)
puts "changelog!: #{msg}"
end
require 'json'
require 'time'
delim = "¿¿¡¡"
allowed_authors = ["miermontoto", "Juan Mier"]
start = Time.now
branch = `git rev-parse --abbrev-ref HEAD`.strip
raw = `git log origin/#{branch} --pretty=format:"%B||%ad||%H||%an#{delim}" --date=short`
log("found #{raw.split(delim).length} commits")
commits = []
raw.split(delim).each do |line|
commit = Commit.new
commit.body, commit.date, commit.hash, commit.author = line.split("||")
commit.author.strip!
commit.hash.strip!
# filter out commits
next unless commit.author in allowed_authors # discard commits from other authors
next if commit.body =~ /Merge pull request/ # discard merge commits
next if commit.body !~ /^\d{1,2}\.\d{1,2}(.*)/ # discard commits that don't have a version number (XX.y)
# process version
commit.version = Version.new
commit.version.major, commit.version.minor = commit.body.match(/^(\d{1,2})\.(\d{1,2})(.*)/).captures
channel_matches = commit.body.match(/(alpha|beta|RC)( ?\d?)/)
if channel_matches then
channel_matches = channel_matches.captures.compact
commit.version.channel = channel_matches.first
commit.version.channel_number = channel_matches.last if channel_matches.length > 1
end
# process commit message
split = commit.body.split("\n")
split.shift unless commits.length == 0
split.shift if split.first == ""
if split.length > 1 then
commit.title = split.first
commit.message = split.drop(1).join("\n")
else
commit.title = commit.body
end
commit.title.strip!
# sanitize HTML content
commit.title = commit.title.gsub(/</, "<").gsub(/>/, ">")
commit.message = commit.message.gsub(/</, "<").gsub(/>/, ">") unless commit.message.nil?
# process markdown code as HTML
commit.title = commit.title.gsub(/`(.*)`/, "<code>\\1</code>")
commit.message = commit.message.gsub(/`(.*)`/, "<code>\\1</code>") unless commit.message.nil?
# skip commits with repeated titles
next if commits.map(&:title).include? commit.title
# bold sections in the commit message (format: "[section]")
commit.message = commit.message.gsub(/\[(.*)\]/, "<b>\[\\1\]</b>") unless commit.message.nil?
# if the first line of the commit message is a newline, remove it
commit.message = commit.message.slice(0, 1) == "\n" ? commit.message.slice(1, commit.message.length) : commit.message unless commit.message.nil?
# ↑ esta es de las líneas más incomprensibles que he escrito en mi vida.
commits << commit
end
# output json to file
File.open("src/content/data/changelog.json", "w") do |f|
f.write(JSON.pretty_generate(commits))
end
log("processed changelog in #{Time.now - start} seconds")