changelogerator 0.0.16 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7139ba15a0c62ce2c9df1eb5a59312b68572c0a92ed0dbbb9190689b58281e18
4
- data.tar.gz: 4feefa1c8e1d0b8104c21e566af4aee6fb10d898109945453a9927d96f20a7cf
3
+ metadata.gz: b292e9657833099e9623ee12bc856d1212fe047a0fc3da90ef7192ab305c2f6d
4
+ data.tar.gz: 24fab3a02631ae80b4ab8b810b8aee5b9fd9340280bfce389247dfb19d215ef6
5
5
  SHA512:
6
- metadata.gz: da1d4ac8c642a14b81a986af888cd852d476073968311bd4e0cdf9685c983529ac9dbfa27cafefbd5c1cd9e1a3af7c97d54b82c9a7d8c6280845a4f9022b7e5b
7
- data.tar.gz: ba9f28d314db9dcb7a01763ce921da9b01a9ee1d9cfa40ed0ee04d160bb467b4e1966824bcb3211f83ca8060111d84a440cf972db2a8de4ea3253a1fba5084d3
6
+ metadata.gz: 28564cd68a1ebd4d4917e8f43339551a144edac68fa242ce1b3248e0f123e9835040d8c267e51755bfb0a3e09a26fb22214605ace98212b9bdc573b54c0265a0
7
+ data.tar.gz: b9c23322c65362bdee0f6535982d4c349bde39092f99457901bebe48d5ba9d77e5484faab552ed81a5f786976024dc68f600eeaa85a34a578a50df6ec560f7dd
@@ -0,0 +1,73 @@
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 = "
20
+ Changelogerator helps you generate a template friendly context made of the changes
21
+ between 2 references on your Github project.
22
+
23
+ Usage:
24
+ changelogerator <repo> [options]"
25
+
26
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
27
+ @options[:verbose] = v
28
+ end
29
+
30
+ opts.on('-fFROM', '--from=FROM', 'From Ref.') do |f|
31
+ @options[:from] = f
32
+ end
33
+
34
+ opts.on('-tTO', '--to=TO', 'To Ref.') do |t|
35
+ @options[:to] = t
36
+ end
37
+
38
+ opts.on('-p', '--[no-]prefix', 'Add (or not) a prefix for the repo') do |p|
39
+ @options[:prefix] = p
40
+ end
41
+
42
+ opts.on('-h', '--help', 'Prints this help') do
43
+ puts opts
44
+ exit
45
+ end
46
+ end.parse!
47
+
48
+ @options[:repo] = ARGV[0]
49
+
50
+ def validate
51
+ raise "Missing value for the 'repo' field" unless @options[:repo]
52
+ raise "Missing value for the 'from' field" unless @options[:from]
53
+ raise "Missing value for the 'to' field" unless @options[:to]
54
+
55
+ true
56
+ end
57
+
58
+ exit 1 unless validate
59
+
60
+ logger.debug('Validation passed')
61
+ logger.debug(format(' - repo: %s', @options[:repo]))
62
+ logger.debug(format(' - from: %s', @options[:from]))
63
+ logger.debug(format(' - to: %s', @options[:to]))
64
+
65
+ cl = Changelog.new(
66
+ @options[:repo],
67
+ @options[:from],
68
+ @options[:to],
69
+ token: ENV['GITHUB_TOKEN'],
70
+ prefix: @options[:prefix]
71
+ )
72
+
73
+ puts cl.to_json
@@ -1,54 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pry'
4
+
3
5
  # A small wrapper class for more easily generating and manipulating Github/Git
4
6
  # changelogs. Given two different git objects (sha, tag, whatever), it will
5
7
  # 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
8
+ # for filtering by label, and the importance of that change (labels), based
7
9
  # on how we classify the importance of PRs in the paritytech/polkadot project.
8
- # Probably not tremendously useful to other projects.
9
10
  class Changelog
10
11
  require 'octokit'
11
12
  require 'git_diff_parser'
13
+ require 'json'
12
14
 
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 || @priorities[0]
51
- end
15
+ attr_accessor :repository, :changes, :meta
16
+ attr_reader :label
52
17
 
53
18
  def self.changes_with_label(changes, label)
54
19
  changes.select do |change|
@@ -56,6 +21,32 @@ class Changelog
56
21
  end
57
22
  end
58
23
 
24
+ # Go through all changes and compute some
25
+ # aggregated values
26
+ def compute_global_meta
27
+ @meta = {}
28
+
29
+ @changes.each do |change|
30
+ # here we remove some of the fields to reduce (considerably) the size
31
+ # of the json output
32
+ change.head = nil
33
+ change.base = nil
34
+ change._links = nil
35
+
36
+ change[:meta].each_key do |meta_key|
37
+ current = change[:meta][meta_key]
38
+
39
+ meta[meta_key] = {} unless meta[meta_key]
40
+ meta[meta_key][:min] = current[:value] if !meta[meta_key][:min] || current[:value] < meta[meta_key][:min]
41
+ meta[meta_key][:max] = current[:value] if !meta[meta_key][:max] || current[:value] > meta[meta_key][:max]
42
+ meta[meta_key][:count] = 0 unless meta[meta_key][:count]
43
+ meta[meta_key][:count] += 1
44
+ end
45
+ end
46
+ end
47
+
48
+ # Return the list of all the files in the changeset
49
+ # that also in the given path
59
50
  def self.changes_files_in_paths?(change, paths)
60
51
  changed_files = GitDiffParser.parse(Octokit.get(change.diff_url)).files
61
52
  paths = [paths] unless paths.is_a? Array
@@ -65,6 +56,18 @@ class Changelog
65
56
  nil
66
57
  end
67
58
 
59
+ # Return the label code for a change
60
+ # if the label name matches the expected pattern.
61
+ # nil otherwise.
62
+ def self.get_label_code(name)
63
+ m = match = name.match(/^([a-z])(\d+)-(.*)$/i)
64
+ if m
65
+ letter, number, text = match.captures
66
+ return [letter, number, text]
67
+ end
68
+ nil
69
+ end
70
+
68
71
  ## End of class methods
69
72
 
70
73
  # github_repo: 'paritytech/polkadot'
@@ -76,44 +79,71 @@ class Changelog
76
79
  # prefix: whether or not to prefix PR numbers with their repo in the changelog
77
80
  def initialize(github_repo, from, to, token: '', prefix: nil)
78
81
  @repo = github_repo
79
- @priorities = self.class.priorities
80
82
  @gh = Octokit::Client.new(
81
83
  access_token: token
82
84
  )
85
+ @repository = @gh.repository(@repo)
83
86
  @prefix = prefix
84
87
  @changes = prs_from_ids(pr_ids_from_git_diff(from, to))
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
88
+ @changes.map do |c|
89
+ compute_change_meta(c)
90
+ end
92
91
 
93
- def runtime_changes?
94
- nil
92
+ compute_global_meta
95
93
  end
96
94
 
97
95
  def add(change)
98
- changes.prepend(prettify_title(apply_priority_to_change(change)))
96
+ compute_change_meta(change)
97
+ prettify_title(change)
98
+ changes.prepend(change)
99
+ @meta = compute_global_meta
99
100
  end
100
101
 
102
+ # Add a pull request from id
101
103
  def add_from_id(id)
102
104
  pull = @gh.pull_request(@repo, id)
103
105
  add pull
104
106
  end
105
107
 
108
+ def to_json(*_args)
109
+ opts = {
110
+ array_nl: "\n",
111
+ object_nl: "\n",
112
+ indent: ' ',
113
+ space_before: ' ',
114
+ space: ' '
115
+ }
116
+ obj = @changes
117
+
118
+ commits = {
119
+ meta: @meta,
120
+ repository: @repository.to_h,
121
+ changes: obj.map(&:to_h)
122
+ }
123
+
124
+ JSON.fast_generate(commits, opts)
125
+ end
126
+
106
127
  private
107
128
 
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] }
129
+ # Compute and attach metadata about one change
130
+ def compute_change_meta(change)
131
+ meta = {}
132
+
133
+ change.labels.each do |label|
134
+ letter, number, text = self.class.get_label_code(label.name)
135
+ next unless letter && number
136
+
137
+ meta[letter] = {
138
+ value: number.to_i,
139
+ text: text
140
+ }
111
141
  end
112
- # Failsafe: add lowest priority if none detected
113
- change[:priority] ||= @priorities[0]
114
- change
142
+
143
+ change['meta'] = meta
115
144
  end
116
145
 
146
+ # Prepend the repo if @prefix is true
117
147
  def prettify_title(pull)
118
148
  pull[:pretty_title] = if @prefix
119
149
  "#{pull[:title]} (#{@repo}##{pull[:number]})"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: changelogerator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Pugh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-25 00:00:00.000000000 Z
11
+ date: 2021-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git_diff_parser
@@ -40,10 +40,12 @@ dependencies:
40
40
  version: '4'
41
41
  description: Simple helper class for paritytech/polkadot changelogs
42
42
  email:
43
- executables: []
43
+ executables:
44
+ - changelogerator
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
48
+ - bin/changelogerator
47
49
  - lib/changelogerator.rb
48
50
  homepage: https://github.com/s3krit/changelogerator
49
51
  licenses:
@@ -57,14 +59,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
59
  requirements:
58
60
  - - ">="
59
61
  - !ruby/object:Gem::Version
60
- version: '0'
62
+ version: '2.7'
61
63
  required_rubygems_version: !ruby/object:Gem::Requirement
62
64
  requirements:
63
65
  - - ">="
64
66
  - !ruby/object:Gem::Version
65
67
  version: '0'
66
68
  requirements: []
67
- rubygems_version: 3.1.2
69
+ rubygems_version: 3.2.22
68
70
  signing_key:
69
71
  specification_version: 4
70
72
  summary: Changelog generation/management