changelogerator 0.0.14 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15c0df34a0b84def4982a8245b7d2fea66d52092941ecfcf761b5c55173670d8
4
- data.tar.gz: c196735034e5aedbbff42ef8b8d822c434baed96c518ad6bedc8f6f61f864fbd
3
+ metadata.gz: 8b7471810cc9cef7c45a8e3e299797131a6535eb3719160b27911f622ed9edc3
4
+ data.tar.gz: 7ba7b175da8540b9faefba07510736f484380ae698aa910480c69de4647220c5
5
5
  SHA512:
6
- metadata.gz: bb8aaaa63b3cea0adc294b6f02a8a21cffdd7dc52e9ef0c3cf4ee46ea06e30535229c8b9a738b03369fb8b87775169c29c4bf46580b97ceba786483849711ded
7
- data.tar.gz: 35952f39e680721b3405aed8d7ce30947c6fc92e41d86942a6fc580a3d856af4ee8682aa8d6b56f7a9d903693346ecfd71e086f59fd7f360730a89a1aba15504
6
+ metadata.gz: c1b900314ed34b4b90de73ad40ebc946aa4e60f40fc3ed9801ad840088739b654452fbe226cf9233bcb881cec2bc7e742c431554cbb2b81209decc769bb2acf9
7
+ data.tar.gz: b413918b6710e7504f7ac1c750a1bdd1c00788f744c3168e25ff0ba85e1b6c13d985d368b3e50da8d872f047c3e072f6a656dbbda69e0e5a3749d2fe973ce02e
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'optparse'
6
+ require_relative '../lib/changelogerator'
7
+ require 'logger'
8
+
9
+ @options = {
10
+ from: nil,
11
+ to: nil
12
+ }
13
+
14
+ logger = Logger.new($stdout)
15
+ logger.level = Logger::WARN
16
+ logger.debug('Starting')
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = 'Changelogerator
20
+
21
+ This utility helps generate a template friendly context made
22
+ of the changes between 2 references on your Github project.
23
+
24
+ Usage:
25
+ changelogerator <repo> [options]'
26
+
27
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
28
+ @options[:verbose] = v
29
+ end
30
+
31
+ opts.on('-fFROM', '--from=FROM', 'From Ref.') do |f|
32
+ @options[:from] = f
33
+ end
34
+
35
+ opts.on('-tTO', '--to=TO', 'To Ref.') do |t|
36
+ @options[:to] = t
37
+ end
38
+
39
+ opts.on('-p', '--[no-]prefix', 'Add (or not) a prefix for the repo') do |p|
40
+ @options[:prefix] = p
41
+ end
42
+
43
+ opts.on('-h', '--help', 'Prints this help') do
44
+ puts opts
45
+ exit
46
+ end
47
+ end.parse!
48
+
49
+ @options[:repo] = ARGV[0]
50
+
51
+ def validate
52
+ raise "Missing value for the 'repo' field" unless @options[:repo]
53
+ raise "Missing value for the 'from' field" unless @options[:from]
54
+ raise "Missing value for the 'to' field" unless @options[:to]
55
+
56
+ true
57
+ end
58
+
59
+ exit 1 unless validate
60
+
61
+ logger.debug('Validation passed')
62
+ logger.debug(format(' - repo: %s', @options[:repo]))
63
+ logger.debug(format(' - from: %s', @options[:from]))
64
+ logger.debug(format(' - to: %s', @options[:to]))
65
+
66
+ cl = Changelog.new(
67
+ @options[:repo],
68
+ @options[:from],
69
+ @options[:to],
70
+ token: ENV['GITHUB_TOKEN'],
71
+ prefix: @options[:prefix]
72
+ )
73
+
74
+ puts cl.to_json
@@ -3,52 +3,15 @@
3
3
  # A small wrapper class for more easily generating and manipulating Github/Git
4
4
  # changelogs. Given two different git objects (sha, tag, whatever), it will
5
5
  # find all PRs that made up that diff and store them as a list. Also allows
6
- # for filtering by label, and the importance of that change (priorities), based
6
+ # for filtering by label, and the importance of that change (labels), based
7
7
  # on how we classify the importance of PRs in the paritytech/polkadot project.
8
- # Probably not tremendously useful to other projects.
9
8
  class Changelog
10
9
  require 'octokit'
11
10
  require 'git_diff_parser'
11
+ require 'json'
12
12
 
13
- attr_accessor :changes
14
- attr_reader :priority
15
-
16
- @priorities = [
17
- {
18
- priority: 1,
19
- label: 'C1-low 📌',
20
- text: 'Upgrade priority: **Low** (upgrade at your convenience)'
21
- },
22
- {
23
- priority: 3,
24
- label: 'C3-medium 📣',
25
- text: 'Upgrade priority: **Medium** (timely upgrade recommended)'
26
- },
27
- {
28
- priority: 7,
29
- label: 'C7-high ❗️',
30
- text: 'Upgrade priority:❗ **HIGH** ❗ Please upgrade your node as soon as possible'
31
- },
32
- {
33
- priority: 9,
34
- label: 'C9-critical ‼️',
35
- text: 'Upgrade priority: ❗❗ **URGENT** ❗❗ PLEASE UPGRADE IMMEDIATELY'
36
- }
37
- ]
38
-
39
- class << self
40
- attr_reader :priorities
41
- end
42
-
43
- # Return highest priority from an array of changes (NOT the actual Changelog
44
- # object)
45
- def self.highest_priority_for_changes(changes)
46
- @priorities.find do |p|
47
- p[:priority] == changes.map do |change|
48
- change[:priority][:priority]
49
- end.max
50
- end
51
- end
13
+ attr_accessor :repository, :changes, :meta
14
+ attr_reader :label
52
15
 
53
16
  def self.changes_with_label(changes, label)
54
17
  changes.select do |change|
@@ -56,6 +19,32 @@ class Changelog
56
19
  end
57
20
  end
58
21
 
22
+ # Go through all changes and compute some
23
+ # aggregated values
24
+ def compute_global_meta
25
+ @meta = {}
26
+
27
+ @changes.each do |change|
28
+ # here we remove some of the fields to reduce (considerably) the size
29
+ # of the json output
30
+ change.head = nil
31
+ change.base = nil
32
+ change._links = nil
33
+
34
+ change[:meta].each_key do |meta_key|
35
+ current = change[:meta][meta_key]
36
+
37
+ meta[meta_key] = {} unless meta[meta_key]
38
+ meta[meta_key][:min] = current[:value] if !meta[meta_key][:min] || current[:value] < meta[meta_key][:min]
39
+ meta[meta_key][:max] = current[:value] if !meta[meta_key][:max] || current[:value] > meta[meta_key][:max]
40
+ meta[meta_key][:count] = 0 unless meta[meta_key][:count]
41
+ meta[meta_key][:count] += 1
42
+ end
43
+ end
44
+ end
45
+
46
+ # Return the list of all the files in the changeset
47
+ # that also in the given path
59
48
  def self.changes_files_in_paths?(change, paths)
60
49
  changed_files = GitDiffParser.parse(Octokit.get(change.diff_url)).files
61
50
  paths = [paths] unless paths.is_a? Array
@@ -65,6 +54,18 @@ class Changelog
65
54
  nil
66
55
  end
67
56
 
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
+
68
69
  ## End of class methods
69
70
 
70
71
  # github_repo: 'paritytech/polkadot'
@@ -76,44 +77,72 @@ class Changelog
76
77
  # prefix: whether or not to prefix PR numbers with their repo in the changelog
77
78
  def initialize(github_repo, from, to, token: '', prefix: nil)
78
79
  @repo = github_repo
79
- @priorities = self.class.priorities
80
80
  @gh = Octokit::Client.new(
81
81
  access_token: token
82
82
  )
83
+ @repository = @gh.repository(@repo)
83
84
  @prefix = prefix
84
- @changes = prs_from_ids(pr_ids_from_git_diff(from, to)).map(&:to_hash)
85
- # add priority to each change
86
- @changes.map { |c| apply_priority_to_change(c) }
87
- end
88
-
89
- def changes_with_label(label)
90
- self.class.changes_with_label(@changes, label)
91
- end
85
+ ids = pr_ids_from_git_diff(from, to)
86
+ @changes = prs_from_ids(ids)
87
+ @changes.map do |c|
88
+ compute_change_meta(c)
89
+ end
92
90
 
93
- def runtime_changes?
94
- nil
91
+ compute_global_meta
95
92
  end
96
93
 
97
94
  def add(change)
98
- changes.prepend(prettify_title(apply_priority_to_change(change)))
95
+ compute_change_meta(change)
96
+ prettify_title(change)
97
+ changes.prepend(change)
98
+ @meta = compute_global_meta
99
99
  end
100
100
 
101
+ # Add a pull request from id
101
102
  def add_from_id(id)
102
103
  pull = @gh.pull_request(@repo, id)
103
104
  add pull
104
105
  end
105
106
 
107
+ def to_json(*_args)
108
+ opts = {
109
+ array_nl: "\n",
110
+ object_nl: "\n",
111
+ indent: ' ',
112
+ space_before: ' ',
113
+ space: ' '
114
+ }
115
+ obj = @changes
116
+
117
+ commits = {
118
+ meta: @meta,
119
+ repository: @repository.to_h,
120
+ changes: obj.map(&:to_h)
121
+ }
122
+
123
+ JSON.fast_generate(commits, opts)
124
+ end
125
+
106
126
  private
107
127
 
108
- def apply_priority_to_change(change)
109
- @priorities.each do |p|
110
- change[:priority] = p if change[:labels].any? { |l| l[:name] == p[:label] }
128
+ # Compute and attach metadata about one change
129
+ def compute_change_meta(change)
130
+ meta = {}
131
+
132
+ change.labels.each do |label|
133
+ letter, number, text = self.class.get_label_code(label.name)
134
+ next unless letter && number
135
+
136
+ meta[letter] = {
137
+ value: number.to_i,
138
+ text: text
139
+ }
111
140
  end
112
- # Failsafe: add lowest priority if none detected
113
- change[:priority] ||= @priorities[0]
114
- change
141
+
142
+ change['meta'] = meta
115
143
  end
116
144
 
145
+ # Prepend the repo if @prefix is true
117
146
  def prettify_title(pull)
118
147
  pull[:pretty_title] = if @prefix
119
148
  "#{pull[:title]} (#{@repo}##{pull[:number]})"
@@ -124,11 +153,13 @@ class Changelog
124
153
  end
125
154
 
126
155
  def pr_ids_from_git_diff(from, to)
127
- @gh.compare(@repo, from, to).commits.map do |c|
156
+ commits = @gh.compare(@repo, from, to).commits
157
+ commits.map do |c|
128
158
  title = c.commit.message.split("\n\n").first
129
- next unless title =~ /\(#[0-9]+\)$/
159
+ regex = /.*#([0-9]+).*$/
160
+ next unless title =~ regex
130
161
 
131
- title.gsub(/.*#([0-9]+)\)$/, '\1')
162
+ title.gsub(regex, '\1')
132
163
  end.compact.map(&:to_i)
133
164
  end
134
165
 
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: changelogerator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Pugh
8
+ - Wilfried Kopp
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2020-10-01 00:00:00.000000000 Z
12
+ date: 2021-11-11 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: git_diff_parser
@@ -38,12 +39,15 @@ dependencies:
38
39
  - - "~>"
39
40
  - !ruby/object:Gem::Version
40
41
  version: '4'
41
- description: Simple helper class for paritytech/polkadot changelogs
42
+ description: A utility to fetch the data required to generate a changelog based on
43
+ change in Github and formatted labels.
42
44
  email:
43
- executables: []
45
+ executables:
46
+ - changelogerator
44
47
  extensions: []
45
48
  extra_rdoc_files: []
46
49
  files:
50
+ - bin/changelogerator
47
51
  - lib/changelogerator.rb
48
52
  homepage: https://github.com/s3krit/changelogerator
49
53
  licenses:
@@ -57,14 +61,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
61
  requirements:
58
62
  - - ">="
59
63
  - !ruby/object:Gem::Version
60
- version: '0'
64
+ version: '2.7'
61
65
  required_rubygems_version: !ruby/object:Gem::Requirement
62
66
  requirements:
63
67
  - - ">="
64
68
  - !ruby/object:Gem::Version
65
69
  version: '0'
66
70
  requirements: []
67
- rubygems_version: 3.1.2
71
+ rubygems_version: 3.2.22
68
72
  signing_key:
69
73
  specification_version: 4
70
74
  summary: Changelog generation/management