changelogerator 0.9.1 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/changelogerator +7 -0
- data/changelogerator.gemspec +21 -0
- data/lib/change.rb +40 -0
- data/lib/changelogerator.rb +45 -30
- data/lib/label.rb +41 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf5410924ba8561481f9ce9130a067d35ce76d42c7b78d002df2059c5b644c6a
|
4
|
+
data.tar.gz: 8567d1755cfa533951d8fdc9567535dd05ca764659c38ee78e21a59783248b79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a10fa4370f7fac47801c47896d3a6367f07fd4855c91b032de7798adad612cf164f19a72f0acd9f3185e3944c64236077548d93689116b96ef8c60969b832892
|
7
|
+
data.tar.gz: 4e72e0a82a7231804f6cb99280b12dadef9b210abca249287882fb80ae01ad3b21fbde3c1e1df2c2dd00ef76c9b7e2209c1f061eb6f6dd2aaecc894bbeae6fa7
|
data/bin/changelogerator
CHANGED
@@ -44,6 +44,13 @@ of the changes between 2 references on your Github project.
|
|
44
44
|
puts opts
|
45
45
|
exit
|
46
46
|
end
|
47
|
+
|
48
|
+
opts.on('-V', '--version', 'Show the version') do
|
49
|
+
gemspec = "#{__dir__}/../changelogerator.gemspec"
|
50
|
+
gem = Gem::Specification.load(gemspec)
|
51
|
+
puts format('%<n>s v%<v>s', { v: gem.version, n: gem.name })
|
52
|
+
exit
|
53
|
+
end
|
47
54
|
end.parse!
|
48
55
|
|
49
56
|
@options[:repo] = ARGV[0]
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'changelogerator'
|
7
|
+
s.version = '0.10.1'
|
8
|
+
s.summary = 'Changelog generation/management'
|
9
|
+
s.authors = ['Martin Pugh', 'Wilfried Kopp']
|
10
|
+
s.files = FileList['lib/**/*.rb', 'bin/changelogerator', 'changelogerator.gemspec']
|
11
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
12
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
13
|
+
s.description = 'A utility to fetch the data required to generate a changelog based on change in Github and formatted labels.'
|
14
|
+
s.require_paths = ['lib']
|
15
|
+
s.license = 'AGPL-3.0'
|
16
|
+
s.homepage = 'https://github.com/s3krit/changelogerator'
|
17
|
+
s.add_runtime_dependency 'git_diff_parser', '~> 3'
|
18
|
+
s.add_runtime_dependency 'octokit', '~> 4'
|
19
|
+
s.required_ruby_version = '>= 2.7'
|
20
|
+
s.metadata = { 'rubygems_mfa_required' => 'true' }
|
21
|
+
end
|
data/lib/change.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'label'
|
4
|
+
|
5
|
+
### A class describe one change that can potentially have several labels
|
6
|
+
class Change
|
7
|
+
attr_reader :labels
|
8
|
+
|
9
|
+
def initialize(labels)
|
10
|
+
# Below we test if we got the full data from Octokit or
|
11
|
+
# only some fake data (label names only) from our tests.
|
12
|
+
@labels = labels.map do |label|
|
13
|
+
if label.respond_to?(:name)
|
14
|
+
from_octokit(label)
|
15
|
+
else
|
16
|
+
from_str(label)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@extra = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def []=(key, value)
|
24
|
+
@extra[key] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def meta
|
28
|
+
@extra['meta']
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def from_octokit(label)
|
34
|
+
Label.new(label.name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def from_str(label_name)
|
38
|
+
Label.new(label_name)
|
39
|
+
end
|
40
|
+
end
|
data/lib/changelogerator.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'label'
|
4
|
+
require 'change'
|
5
|
+
|
3
6
|
# A small wrapper class for more easily generating and manipulating Github/Git
|
4
7
|
# changelogs. Given two different git objects (sha, tag, whatever), it will
|
5
8
|
# find all PRs that made up that diff and store them as a list. Also allows
|
@@ -32,13 +35,19 @@ class Changelog
|
|
32
35
|
change._links = nil
|
33
36
|
|
34
37
|
change[:meta].each_key do |meta_key|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
aggregate = change[:meta][meta_key]['agg']
|
39
|
+
|
40
|
+
if meta[meta_key]
|
41
|
+
meta[meta_key][:min] = aggregate['min'] if aggregate['min'] < meta[meta_key][:min]
|
42
|
+
meta[meta_key][:max] = aggregate['max'] if aggregate['max'] > meta[meta_key][:max]
|
43
|
+
meta[meta_key][:count] += aggregate['count']
|
44
|
+
else
|
45
|
+
meta[meta_key] = {
|
46
|
+
min: aggregate['min'],
|
47
|
+
max: aggregate['max'],
|
48
|
+
count: aggregate['count']
|
49
|
+
}
|
50
|
+
end
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
@@ -54,18 +63,6 @@ class Changelog
|
|
54
63
|
nil
|
55
64
|
end
|
56
65
|
|
57
|
-
# Return the label code for a change
|
58
|
-
# if the label name matches the expected pattern.
|
59
|
-
# nil otherwise.
|
60
|
-
def self.get_label_code(name)
|
61
|
-
m = match = name.match(/^([a-z])(\d+)-(.*)$/i)
|
62
|
-
if m
|
63
|
-
letter, number, text = match.captures
|
64
|
-
return [letter, number, text]
|
65
|
-
end
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
|
69
66
|
## End of class methods
|
70
67
|
|
71
68
|
# github_repo: 'paritytech/polkadot'
|
@@ -83,16 +80,17 @@ class Changelog
|
|
83
80
|
@repository = @gh.repository(@repo)
|
84
81
|
@prefix = prefix
|
85
82
|
ids = pr_ids_from_git_diff(from, to)
|
83
|
+
# The following takes very long time
|
86
84
|
@changes = prs_from_ids(ids)
|
87
85
|
@changes.map do |c|
|
88
|
-
compute_change_meta(c)
|
86
|
+
self.class.compute_change_meta(c)
|
89
87
|
end
|
90
88
|
|
91
89
|
compute_global_meta
|
92
90
|
end
|
93
91
|
|
94
92
|
def add(change)
|
95
|
-
compute_change_meta(change)
|
93
|
+
self.class.compute_change_meta(change)
|
96
94
|
prettify_title(change)
|
97
95
|
changes.prepend(change)
|
98
96
|
@meta = compute_global_meta
|
@@ -123,25 +121,41 @@ class Changelog
|
|
123
121
|
JSON.fast_generate(commits, opts)
|
124
122
|
end
|
125
123
|
|
126
|
-
private
|
127
|
-
|
128
124
|
# Compute and attach metadata about one change
|
129
|
-
def compute_change_meta(change)
|
125
|
+
def self.compute_change_meta(change)
|
130
126
|
meta = {}
|
131
127
|
|
132
|
-
change.labels.each do |
|
133
|
-
|
134
|
-
|
128
|
+
change.labels.each do |lbl|
|
129
|
+
label = Label.new(lbl.name)
|
130
|
+
|
131
|
+
next unless label
|
132
|
+
|
133
|
+
if meta.key?(label.letter)
|
134
|
+
aggregate = meta[label.letter]['agg']
|
135
|
+
aggregate['max'] = label.number if label.number > aggregate['max']
|
136
|
+
aggregate['min'] = label.number if label.number < aggregate['min']
|
137
|
+
aggregate['count'] += 1
|
138
|
+
else
|
139
|
+
meta[label.letter] = {
|
140
|
+
'agg' => {
|
141
|
+
'count' => 1,
|
142
|
+
'max' => label.number,
|
143
|
+
'min' => label.number
|
144
|
+
}
|
145
|
+
}
|
146
|
+
end
|
135
147
|
|
136
|
-
meta[letter] = {
|
137
|
-
value
|
138
|
-
text
|
148
|
+
meta[label.letter]["#{label.letter}#{label.number}"] = {
|
149
|
+
'value' => label.number,
|
150
|
+
'text' => label.description
|
139
151
|
}
|
140
152
|
end
|
141
153
|
|
142
154
|
change['meta'] = meta
|
143
155
|
end
|
144
156
|
|
157
|
+
private
|
158
|
+
|
145
159
|
# Prepend the repo if @prefix is true
|
146
160
|
def prettify_title(pull)
|
147
161
|
pull[:pretty_title] = if @prefix
|
@@ -163,6 +177,7 @@ class Changelog
|
|
163
177
|
end.compact.map(&:to_i)
|
164
178
|
end
|
165
179
|
|
180
|
+
# TODO: See if we can make this quicker
|
166
181
|
def prs_from_ids(ids)
|
167
182
|
batch_size = 100
|
168
183
|
prs = []
|
data/lib/label.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
### Label = Letter + Number [+ Description]
|
4
|
+
class Label
|
5
|
+
attr_accessor :letter, :number, :description
|
6
|
+
|
7
|
+
# Return the label letter for a change if the label name matches the expected pattern.
|
8
|
+
# nil otherwise.
|
9
|
+
def parse(label)
|
10
|
+
m = match = label.match(/^([a-z])(\d+)\s*-?\s*(.*)$/i)
|
11
|
+
return nil unless m
|
12
|
+
|
13
|
+
letter, digits, text = match.captures
|
14
|
+
number = digits.to_i
|
15
|
+
[letter, number, text]
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(input)
|
19
|
+
raise InvalidInput, 'Invalid, it must be a non-empty string' unless input
|
20
|
+
|
21
|
+
p = parse(input)
|
22
|
+
raise InvalidLabel, format('Invalid label "%<input>s"', { input: input }) unless p
|
23
|
+
|
24
|
+
@letter = p[0].upcase
|
25
|
+
@number = p[1]
|
26
|
+
@description = p[2] unless p[2].empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
### Implemented for compatibility reasons
|
30
|
+
def name
|
31
|
+
to_str
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_str
|
35
|
+
format('%<l>s%<n>d - %<d>s', { l: @letter, n: @number, d: @description })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class InvalidLabel < StandardError; end
|
40
|
+
|
41
|
+
class InvalidInput < StandardError; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: changelogerator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Pugh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: git_diff_parser
|
@@ -48,11 +48,15 @@ extensions: []
|
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
50
|
- bin/changelogerator
|
51
|
+
- changelogerator.gemspec
|
52
|
+
- lib/change.rb
|
51
53
|
- lib/changelogerator.rb
|
54
|
+
- lib/label.rb
|
52
55
|
homepage: https://github.com/s3krit/changelogerator
|
53
56
|
licenses:
|
54
57
|
- AGPL-3.0
|
55
|
-
metadata:
|
58
|
+
metadata:
|
59
|
+
rubygems_mfa_required: 'true'
|
56
60
|
post_install_message:
|
57
61
|
rdoc_options: []
|
58
62
|
require_paths:
|
@@ -68,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
72
|
- !ruby/object:Gem::Version
|
69
73
|
version: '0'
|
70
74
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.4.6
|
72
76
|
signing_key:
|
73
77
|
specification_version: 4
|
74
78
|
summary: Changelog generation/management
|