committer-tools 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: 1affe04dad34132bc8fced2cb164ced45c2fb0b6
4
- data.tar.gz: 8851d93082f8e38ba7768688bd643973fecefdea
3
+ metadata.gz: 4f27491ec9dd9013f8a904670616d75b24104ed0
4
+ data.tar.gz: 0abe91d59fad9d7bf04198a39a89bdaa9ad612b7
5
5
  SHA512:
6
- metadata.gz: 19aac12185440f7b6e37b3dfad50b5e00ee25857edef54aa51e3570f3d723571bf471c88c8cfe43347aece26ae30350a102436851c324df3037cf80bc12784f2
7
- data.tar.gz: fabb7fe46b238a98ea169a9255036dcd45a252e740f34950f779034c98544579ee651f052340349db6bc41dc60e03a8feb94688d1a4b71d7573ebfddfac994d9
6
+ metadata.gz: a2d65c2d115afcb9b730523dee35d2b5abc2683c06efa9499097b12a4f2bf519392cd58623117e7531b838085c7d8217a64a3d41271c69b9cc43b1ae523dd94d
7
+ data.tar.gz: 8c19598e5de009b554f6cf655e76954e85f4a8c1a6cf58155f61292cde40827cf8187d0027ba7152d0ca07df8c254845a32849942c729f0580590923854ab743
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'minitest'
3
4
  gem 'pry'
4
5
  gem 'rake'
5
6
  gem 'rb-readline'
data/Gemfile.lock CHANGED
@@ -10,6 +10,7 @@ GEM
10
10
  mime-types (3.1)
11
11
  mime-types-data (~> 3.2015)
12
12
  mime-types-data (3.2016.0521)
13
+ minitest (5.10.3)
13
14
  netrc (0.11.0)
14
15
  pry (0.11.2)
15
16
  coderay (~> 1.1.0)
@@ -28,6 +29,7 @@ PLATFORMS
28
29
  ruby
29
30
 
30
31
  DEPENDENCIES
32
+ minitest
31
33
  pry
32
34
  rake
33
35
  rb-readline
data/Rakefile CHANGED
@@ -1,3 +1,11 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
3
  require 'bundler/gem_tasks'
4
+
5
+ require "rake/testtask"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.libs << "lib"
10
+ t.test_files = FileList["test/**/*_test.rb"]
11
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'committer-tools'
5
- spec.version = '0.1.1'
5
+ spec.version = '0.1.2'
6
6
  spec.authors = 'Jon Moss'
7
7
  spec.email = 'me@jonathanmoss.me'
8
8
 
@@ -1,8 +1,19 @@
1
1
  require 'json'
2
2
  require 'rest-client'
3
3
 
4
+ class HTTPHelper
5
+ def self.get(url)
6
+ RestClient.get(url, { params: { access_token: ENV['GH_TOKEN'] } }).body
7
+ end
8
+
9
+ def self.get_json(url)
10
+ JSON.parse(get(url))
11
+ end
12
+ end
13
+
4
14
  class Lander
5
- def run(pr, metadata)
15
+ def run(pr, github_pr, metadata)
16
+ check_to_land(github_pr, metadata)
6
17
  introduce_commit(pr, metadata)
7
18
 
8
19
  puts "[\u{2714}] Commit(s) applied locally. Please update to your liking, and then type 'continue'."
@@ -27,6 +38,24 @@ class Lander
27
38
  `git commit --amend -m '#{msg}'`
28
39
  end
29
40
 
41
+ def check_to_land(github_pr, metadata)
42
+ # At least 48 hours of review time
43
+ if Time.parse(github_pr['created_at']) > (Date.today - 2).to_time
44
+ puts "[✘] PR must remain open for at least 48 hours"
45
+ end
46
+
47
+ # At least two approvals
48
+ if (metadata[:reviewers].length < 2)
49
+ puts "[✘] PR must have at least two reviewers"
50
+ end
51
+
52
+ # No failing CI builds
53
+ failing_statuses = metadata[:ci_statuses].select { |job| job[:status] == 'failure' }
54
+ if (failing_statuses.length > 0)
55
+ puts "[✘] Failing builds on #{failing_statuses.map { |s| s[:name] }.join(', ')}"
56
+ end
57
+ end
58
+
30
59
  def introduce_commit(pr, metadata)
31
60
  # Clear current status
32
61
  `git am --abort`
@@ -47,125 +76,91 @@ class Lander
47
76
  end
48
77
  end
49
78
 
50
- class Preparer
51
- class MetadataCollector
52
- NODE_README_URL = 'https://raw.githubusercontent.com/nodejs/node/master/README.md'
53
- REVIEWER_REGEX = /\* \[(.+?)\]\(.+?\) -\s\*\*(.+?)\*\* &lt;(.+?)&gt;/m
54
-
55
- def initialize(github_pr)
56
- @github_pr = github_pr
57
- end
79
+ class MetadataCollector
80
+ NODE_README_URL = 'https://raw.githubusercontent.com/nodejs/node/master/README.md'
81
+ REVIEWER_REGEX = /\* \[(.+?)\]\(.+?\) -\s\*\*(.+?)\*\* &lt;(.+?)&gt;/m
58
82
 
59
- def collect
60
- {
61
- pr_url: collect_pr_url,
62
- reviewers: collect_reviewers,
63
- ci_statuses: collect_ci_statuses
64
- }
65
- end
83
+ def collect(github_pr)
84
+ {
85
+ pr_url: collect_pr_url(github_pr),
86
+ reviewers: collect_reviewers(github_pr),
87
+ ci_statuses: collect_ci_statuses(github_pr)
88
+ }
89
+ end
66
90
 
67
- private
91
+ private
68
92
 
69
- def collect_ci_statuses
70
- JSON.parse(
71
- RestClient.get(
72
- @github_pr['statuses_url'],
73
- { params: { access_token: ENV['GH_TOKEN'] } }
74
- )
75
- ).map do |status|
76
- { name: status['context'], status: status['state'] }
77
- end
93
+ def collect_ci_statuses(github_pr)
94
+ HTTPHelper.get_json(github_pr['statuses_url']).map do |status|
95
+ { name: status['context'], status: status['state'] }
78
96
  end
97
+ end
79
98
 
80
- def collect_pr_url
81
- "PR-URL: #{@github_pr['html_url']}"
82
- end
99
+ def collect_pr_url(github_pr)
100
+ "PR-URL: #{github_pr['html_url']}"
101
+ end
83
102
 
84
- def collect_reviewers
85
- # Collect a list of all possible reviewers
86
- possible_reviewers = {}
87
- readme = RestClient.get(NODE_README_URL, { params: { access_token: ENV['GH_TOKEN'] } }).body
88
-
89
- # GitHub being stupid...
90
- # Treat every two lines as one...
91
- readme.split("\n").each_slice(2).to_a.each do |a, b|
92
- if (m = REVIEWER_REGEX.match("#{a} #{b}"))
93
- possible_reviewers[m[1]] = {
94
- name: m[2],
95
- email: m[3]
96
- }
97
- end
103
+ def collect_reviewers(github_pr)
104
+ # Collect a list of all possible reviewers
105
+ possible_reviewers = {}
106
+ readme = HTTPHelper.get(NODE_README_URL)
107
+
108
+ # GitHub being stupid...
109
+ # Treat every two lines as one...
110
+ readme.split("\n").each_slice(2).to_a.each do |a, b|
111
+ if (m = REVIEWER_REGEX.match("#{a} #{b}"))
112
+ possible_reviewers[m[1]] = {
113
+ name: m[2],
114
+ email: m[3]
115
+ }
98
116
  end
117
+ end
99
118
 
100
- # Use this list to identify reviewers for the current PR!
101
- reviewer_usernames = JSON.parse(RestClient.get("#{@github_pr['url']}/reviews", { params: { access_token: ENV['GH_TOKEN'] } })).map do |review|
102
- next unless review['state'] == 'APPROVED'
103
- review['user']['login']
104
- end.compact.uniq
119
+ # Use this list to identify reviewers for the current PR!
120
+ reviewer_usernames = HTTPHelper.get_json("#{github_pr['url']}/reviews").map do |review|
121
+ next unless review['state'] == 'APPROVED'
122
+ review['user']['login']
123
+ end.compact.uniq
105
124
 
106
- reviewer_usernames.map do |reviewer_username|
107
- user = possible_reviewers[reviewer_username]
125
+ reviewer_usernames.map do |reviewer_username|
126
+ user = possible_reviewers[reviewer_username]
108
127
 
109
- "Reviewed-By: #{user[:name]} <#{user[:email]}>"
110
- end
128
+ "Reviewed-By: #{user[:name]} <#{user[:email]}>"
111
129
  end
112
130
  end
131
+ end
113
132
 
114
- def initialize
115
- @pr = {}
116
- @github_pr = {}
117
- @metadata = {}
118
- end
119
-
133
+ class Preparer
120
134
  def run
121
- @pr = get_pr()
122
- @github_pr = get_github_pr(@pr)
123
- @metadata = get_metadata(@github_pr)
124
- check_to_land(@github_pr, @metadata)
135
+ pr = get_pr()
136
+ github_pr = get_github_pr(pr)
137
+ metadata = get_metadata(github_pr)
125
138
 
126
- Lander.new.run(@pr, @metadata)
139
+ Lander.new.run(pr, github_pr, metadata)
127
140
  end
128
141
 
129
142
  private
130
143
 
131
- def check_to_land(github_pr, metadata)
132
- # At least 48 hours of review time
133
- if Time.parse(github_pr['created_at']) > (Date.today - 2).to_time
134
- puts "[✘] PR must remain open for at least 48 hours"
135
- end
136
-
137
- # At least two approvals
138
- if (metadata[:reviewers].length < 2)
139
- puts "[✘] PR must have at least two reviewers"
140
- end
141
-
142
- # No failing CI builds
143
- failing_statuses = metadata[:ci_statuses].select { |job| job[:status] == 'failure' }
144
- if (failing_statuses.length > 0)
145
- puts "[✘] Failing builds on #{failing_statuses.map { |s| s[:name] }.join(', ')}"
146
- end
147
- end
148
-
149
144
  def get_github_pr(pr)
150
- JSON.parse(
151
- RestClient.get(
152
- "https://api.github.com/repos/#{pr[:org]}/#{pr[:repo]}/pulls/#{pr[:id]}",
153
- { params: { access_token: ENV['GH_TOKEN'] } }
154
- )
145
+ HTTPHelper.get_json(
146
+ "https://api.github.com/repos/#{pr[:org]}/#{pr[:repo]}/pulls/#{pr[:id]}"
155
147
  )
156
148
  end
157
149
 
158
150
  def get_metadata(github_pr)
159
- MetadataCollector.new(github_pr).collect
151
+ MetadataCollector.new.collect(github_pr)
160
152
  end
161
153
 
162
154
  def get_pr
163
155
  puts "Please enter PR ID:"
164
156
  pr_id = gets.strip!
165
157
 
166
- org, repo_and_id = pr_id.split('/')
167
- repo, id = repo_and_id.split('#')
168
-
169
- { org: org, repo: repo, id: id }
158
+ begin
159
+ org, repo_and_id = pr_id.split('/')
160
+ repo, id = repo_and_id.split('#')
161
+ { org: org, repo: repo, id: id }
162
+ rescue
163
+ raise "Invalid PR ID: #{pr_id}"
164
+ end
170
165
  end
171
166
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: committer-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Moss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-06 00:00:00.000000000 Z
11
+ date: 2017-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client