bundler-audited_update 0.2.0 → 0.3.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: 1643d8c2c255b6e6b6aa935f7f9d9703a9218e4f28fbd9b3985922d59e98abdf
4
- data.tar.gz: 2e45069ebfc4b3d036173628837f5fabb97397b16e99181d9145969601309909
3
+ metadata.gz: 55ee9261d8740b888e04057710f5a0b25b6155ca49fcae312702afba4ff9762b
4
+ data.tar.gz: dc14cf4a44acb080253bf2ae3f369f8b4ae62f948c532a98a1bb36d665795f34
5
5
  SHA512:
6
- metadata.gz: c8febdb50ed26521ef4be10736d606ebcd8d3a5960f6d73a4eb32415ac092e314c83302d301042058c429f6c4ecf0fdf26e98a802586231a82f706e7339efab3
7
- data.tar.gz: 6e9bbb78c2f333555143ed05c88b922417430c13929da830210e873a07d238148fe08ca006463a9942c9bc110106eceef293421c02fa35ef96b73c1c3f02ca2e
6
+ metadata.gz: 2f256a3a79e6f20e4a5d054fc4e519e364ce902f006be752098ff3d9e17b93887079d16e0a1b7fd869f1de49d1f4e7f8f194abce6a4996c37a45afa492521783
7
+ data.tar.gz: a97bdd6cf867e5f4661741c8f643adb83c5d618fed11ea9aa0d373fdd4f56b19576123c74a0ad432470112546c2be38a9af9b023c61a5b835b07bdfb09e66b4f
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/audited_update"
4
+ require 'bundler/audited_update'
4
5
 
5
6
  Bundler::AuditedUpdate.new.run!
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  require 'bundler/lockfile_parser'
3
- require "bundler/cli"
4
- require "bundler/cli/update"
5
- require "open-uri"
5
+ require 'bundler/cli'
6
+ require 'bundler/cli/update'
7
+ require 'open-uri'
6
8
  require 'net/http'
7
9
  require 'json'
8
10
  require 'versionomy'
@@ -10,25 +12,31 @@ require 'launchy'
10
12
 
11
13
  module Bundler
12
14
  class AuditedUpdate
15
+ CHANGELOG_URLS = {
16
+ "graphql-pro" => "https://github.com/rmosolgo/graphql-ruby/blob/master/CHANGELOG-pro.md",
17
+ "sidekiq" => "https://github.com/mperham/sidekiq/blob/main/Changes.md",
18
+ "faraday" => "https://github.com/lostisland/faraday/releases"
19
+ }
20
+
13
21
  def run!
14
22
  @before_specs = gem_specs
15
23
  bundle_update
16
24
  @after_specs = gem_specs
17
25
 
18
- @output = ""
26
+ @output = ''
19
27
  @output += "# Gem Changes\n"
20
28
  @output += "\n"
21
29
 
22
- output_gems("Added Gems", added_gems)
23
- output_gems("Removed Gems", removed_gems)
30
+ output_gems('Added Gems', added_gems)
31
+ output_gems('Removed Gems', removed_gems)
24
32
  output_changed_gems(changed_gems)
25
33
 
26
34
  puts "\n\n\n\n\n"
27
35
 
28
- puts "--------------------------------"
29
- puts "Upgraded Gems"
30
- puts "(Generated with bundler-audited_updated https://github.com/bmulholland/audited_bundle_update)"
31
- puts "--------------------------------"
36
+ puts '--------------------------------'
37
+ puts 'Upgraded Gems'
38
+ puts '(Generated with bundler-audited_updated https://github.com/bmulholland/audited_bundle_update)'
39
+ puts '--------------------------------'
32
40
 
33
41
  puts @output
34
42
  end
@@ -46,16 +54,20 @@ module Bundler
46
54
  def output_changed_gems(gems)
47
55
  return if gems.empty?
48
56
 
49
- major_upgrades = gems.select {|_, versions| versions[:before].major != versions[:after].major }
50
- minor_upgrades = gems.select {|name, versions| !major_upgrades.keys.include?(name) && versions[:before].minor != versions[:after].minor }
51
- point_upgrades = gems.reject { |name, _| major_upgrades.keys.include?(name) || minor_upgrades.keys.include?(name) }
57
+ major_upgrades = gems.reject { |_, versions| versions[:before].major == versions[:after].major }
58
+ minor_upgrades = gems.select do |name, versions|
59
+ !major_upgrades.keys.include?(name) && versions[:before].minor != versions[:after].minor
60
+ end
61
+ point_upgrades = gems.reject do |name, _|
62
+ major_upgrades.keys.include?(name) || minor_upgrades.keys.include?(name)
63
+ end
52
64
 
53
65
  @output += "## Upgraded Gems\n"
54
66
  @output += "\n"
55
67
 
56
- output_changed_gems_section("Major", major_upgrades)
57
- output_changed_gems_section("Minor", minor_upgrades)
58
- output_changed_gems_section("Point", point_upgrades)
68
+ output_changed_gems_section('Major', major_upgrades)
69
+ output_changed_gems_section('Minor', minor_upgrades)
70
+ output_changed_gems_section('Point', point_upgrades)
59
71
 
60
72
  @output += "\n"
61
73
  end
@@ -69,82 +81,137 @@ module Bundler
69
81
  end
70
82
 
71
83
  def gem_output(name, version)
72
- if version.is_a? Hash
73
- version_string = "#{version[:before]} -> #{version[:after]}"
74
- info = gem_info(name, version[:after])
84
+ # gems that are continuously released and therefore have no helpful
85
+ # changelog
86
+ continuously_released_gems = %w[aws-partitions aws-sdk-core sorbet sorbet-runtime
87
+ sorbet-static-and-runtime]
88
+
89
+ if continuously_released_gems.include?(name)
90
+ puts "\n\n\n"
91
+ puts '--------------------------------'
92
+ puts "#{name} updated"
93
+ puts '--------------------------------'
94
+
95
+ if version.is_a? Hash
96
+ info = gem_info(name, version[:after])
97
+ version_string = "#{version[:before]} -> #{version[:after]}"
98
+ else
99
+ info = gem_info(name, version)
100
+ version_string = version
101
+ end
75
102
 
76
103
  guessed_source = gem_source_url(info)
104
+ change_detail = guessed_source
77
105
 
78
- if guessed_source
79
- changelog_text, changelog_url = guess_changelog(guessed_source)
80
-
81
- if changelog_text && !changelog_text.empty?
82
- puts "\n\n\n"
83
- puts "--------------------------------"
84
- puts "#{name} changes from #{version_string}"
85
- puts "--------------------------------"
86
- # Output the changelog text from top until the line that contains the previous version
87
- changelog_output = changelog_text.split(/^.*#{Regexp.escape(version[:before].to_s)}/, 2).first
88
- # Max 200 lines
89
- changelog_output = changelog_output.lines.to_a[0...200].join
90
- puts changelog_output
91
- impact = nil
92
- while impact.nil?
93
- puts "Does #{name} #{version_string} impact your application? (y/n/[o]pen in browser)"
94
- answer = gets
95
- answer = answer.downcase.strip
96
- if answer == "y"
97
- puts "What's a short description of the impact?"
98
- impact = gets
99
- elsif answer == "n"
100
- impact = "No impact"
101
- elsif answer == "o"
102
- Launchy.open(changelog_url)
103
- else
104
- puts "Invalid answer"
105
- end
106
- end
106
+ puts 'This gem is continuously updated, with no meaningful changelog.'
107
+
108
+ impact = nil
109
+ while impact.nil?
110
+ puts "Does #{name} #{version_string} impact your application? (y/n/[o]pen in browser)"
111
+ answer = gets
112
+ answer = answer.downcase.strip
113
+ case answer
114
+ when 'y'
115
+ puts "What's a short description of the impact?"
116
+ impact = gets
117
+ when 'n'
118
+ impact = 'No impact'
119
+ when 'o'
120
+ Launchy.open(guessed_source)
121
+ else
122
+ puts 'Invalid answer'
123
+ end
124
+ end
125
+
126
+ change_detail = impact
107
127
 
108
- change_detail = impact
128
+ elsif version.is_a? Hash
129
+ version_string = "#{version[:before]} -> #{version[:after]}"
130
+ info = gem_info(name, version[:after])
131
+
132
+ changelog_text, changelog_url = guess_changelog(
133
+ name, gem_source_url(info)
134
+ )
135
+
136
+ if changelog_text && !changelog_text.empty?
137
+ puts "\n\n\n"
138
+ puts '--------------------------------'
139
+ puts "#{name} changes from #{version_string}"
140
+ puts '--------------------------------'
141
+
142
+ # Output the changelog text from top until the line that contains the previous version
143
+ changelog_output = changelog_text.split(/^.*#{Regexp.escape(version[:before].to_s)}/, 2).first
144
+
145
+ # Max 200 lines
146
+ changelog_output = changelog_output.lines.to_a[0...200].join
147
+
148
+ puts changelog_output
149
+ impact = nil
150
+ while impact.nil?
151
+ puts "Does #{name} #{version_string} impact your application? (y/n/[o]pen in browser)"
152
+ answer = gets
153
+ answer = answer.downcase.strip
154
+ case answer
155
+ when 'y'
156
+ puts "What's a short description of the impact?"
157
+ impact = gets
158
+ when 'n'
159
+ impact = 'No impact'
160
+ when 'o'
161
+ Launchy.open(changelog_url)
162
+ else
163
+ puts 'Invalid answer'
164
+ end
109
165
  end
166
+
167
+ change_detail = impact
110
168
  end
111
169
 
112
170
  else
113
171
  version_string = version
114
172
  info = gem_info(name, version)
115
- guessed_source = gem_source_url(info)
116
- change_detail = guessed_source
173
+ change_detail = gem_source_url(info)
117
174
  end
118
175
 
119
- change_detail ||= "Unsupported source URL, cannot search for changelog"
120
-
176
+ change_detail ||= 'Unsupported source URL, cannot search for changelog'
121
177
 
122
178
  @output += "* #{name} (#{version_string}): #{change_detail}\n"
123
179
  end
124
180
 
125
- def guess_changelog(root_url)
126
- filenames = %w{
127
- CHANGELOG
128
- CHANGELOG.md
129
- Changelog
130
- Changelog.md
131
- History
132
- History.md
133
- HISTORY.md
134
- History.rdoc
135
- Changes
136
- CHANGES
137
- CHANGES.md
138
- NEWS
139
- }
181
+ def guess_changelog(name, root_url)
182
+ # There are always going to be exceptions, so just hardcode those.
183
+ root_url = CHANGELOG_URLS[name] if CHANGELOG_URLS.key?(name)
184
+
185
+ return nil unless root_url
186
+
187
+ filenames = %w[
188
+ CHANGELOG
189
+ CHANGELOG.md
190
+ Changelog
191
+ Changelog.md
192
+ History
193
+ History.md
194
+ HISTORY.md
195
+ History.rdoc
196
+ Changes
197
+ CHANGES
198
+ CHANGES.md
199
+ NEWS
200
+ ]
140
201
  changelog_text = nil
141
202
  changelog_url = nil
142
203
 
143
- filenames.each do |filename|
144
- changelog_text = try_changelog_url(root_url, filename)
145
- if changelog_text
146
- changelog_url = changelog_url_for(root_url, filename)
147
- break
204
+ root_url_is_releases_page = root_url.end_with?("/releases")
205
+
206
+ changelog_url = root_url if root_url_is_releases_page
207
+
208
+ unless changelog_url
209
+ filenames.each do |filename|
210
+ changelog_text = try_changelog_url(root_url, filename)
211
+ if changelog_text
212
+ changelog_url = changelog_url_for(root_url, filename)
213
+ break
214
+ end
148
215
  end
149
216
  end
150
217
 
@@ -154,7 +221,7 @@ module Bundler
154
221
  end
155
222
 
156
223
  unless changelog_text
157
- changelog_text = "Could not find changelog URL, try manually"
224
+ changelog_text = 'Could not find changelog URL, try manually'
158
225
  changelog_url = root_url
159
226
  end
160
227
 
@@ -162,8 +229,10 @@ module Bundler
162
229
  end
163
230
 
164
231
  def gem_source_url(info)
165
- source_url_guess = info["source_code_uri"] || info["homepage_uri"]
166
- if source_url_guess&.include?("github.com")
232
+ return nil unless info
233
+
234
+ source_url_guess = info['source_code_uri'] || info['homepage_uri']
235
+ if source_url_guess&.include?('github.com')
167
236
  source_url_guess
168
237
  else
169
238
  # Unsupported source URL
@@ -172,22 +241,22 @@ module Bundler
172
241
  end
173
242
 
174
243
  def added_gems
175
- @after_specs.reject {|spec| @before_specs.map(&:name).include?(spec.name) }
244
+ @after_specs.reject { |spec| @before_specs.map(&:name).include?(spec.name) }
176
245
  end
177
246
 
178
247
  def removed_gems
179
- @before_specs.reject {|spec| @after_specs.map(&:name).include?(spec.name) }
248
+ @before_specs.reject { |spec| @after_specs.map(&:name).include?(spec.name) }
180
249
  end
181
250
 
182
251
  def changed_gems
183
252
  gems = @after_specs.reject do |after_spec|
184
- before_spec = @before_specs.find {|before_spec| before_spec && before_spec.name == after_spec.name }
253
+ before_spec = @before_specs.find { |before_spec| before_spec && before_spec.name == after_spec.name }
185
254
  !before_spec || before_spec.version == after_spec.version
186
255
  end
187
256
 
188
257
  gems.map! do |the_gem|
189
- before_gem = @before_specs.find {|before_spec| before_spec.name == the_gem.name }
190
- after_gem = @after_specs.find {|after_spec| after_spec.name == the_gem.name }
258
+ before_gem = @before_specs.find { |before_spec| before_spec.name == the_gem.name }
259
+ after_gem = @after_specs.find { |after_spec| after_spec.name == the_gem.name }
191
260
  versions = {
192
261
  before: Versionomy.parse(before_gem.version.to_s),
193
262
  after: Versionomy.parse(after_gem.version.to_s)
@@ -199,42 +268,47 @@ module Bundler
199
268
  end
200
269
 
201
270
  def github_releases_url(source_root)
202
- api_source_root = source_root.gsub("github.com/", "api.github.com/repos/")
203
- "#{api_source_root}/releases"
271
+ api_source_root = source_root.gsub('github.com/', 'api.github.com/repos/')
272
+ api_source_root.end_with?("/releases") ? api_source_root : "#{api_source_root}/releases"
204
273
  end
205
274
 
206
275
  def github_releases_bodies(source_root)
207
276
  response = ::URI.parse(github_releases_url(source_root)).read
208
277
  releases = JSON.parse(response)
209
- release_notes = ""
278
+ release_notes = ''
210
279
  releases.each do |release|
211
- next unless release["body"]
212
- release_notes += release["name"]
280
+ next unless release['body']
281
+
282
+ release_notes += release['name']
213
283
  release_notes += "\n"
214
- release_notes += release["body"]
284
+ release_notes += release['body']
215
285
  release_notes += "\n"
216
286
  release_notes += "\n"
217
287
  end
218
288
  release_notes
219
289
  rescue OpenURI::HTTPError
220
- return nil
290
+ nil
221
291
  end
222
292
 
223
293
  def changelog_url_for(source_root, filename)
224
- raw_source_root = source_root.gsub("github.com", "raw.githubusercontent.com")
294
+ raw_source_root = source_root.gsub('github.com', 'raw.githubusercontent.com')
225
295
  url = "#{raw_source_root}/master/#{filename}"
226
296
  end
227
297
 
228
298
  def try_changelog_url(source_root, filename)
229
299
  ::URI.parse(changelog_url_for(source_root, filename)).read
230
300
  rescue OpenURI::HTTPError
231
- return nil
301
+ nil
232
302
  end
233
303
 
234
304
  def gem_info(name, version)
235
305
  gem_url = "https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}"
236
306
  response = ::URI.parse(gem_url).read
237
307
  JSON.parse(response)
308
+ rescue OpenURI::HTTPError => e
309
+ # return nil for 404 - which means the gem doens't exist on rubygems,
310
+ # probably private
311
+ raise unless e.message.include?('404')
238
312
  end
239
313
 
240
314
  def gem_specs
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-audited_update
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Mulholland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-07 00:00:00.000000000 Z
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: versionomy
42
+ name: launchy
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: launchy
56
+ name: versionomy
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -79,7 +79,8 @@ files:
79
79
  homepage: http://rubygems.org/gems/bundler-audited_update
80
80
  licenses:
81
81
  - MIT
82
- metadata: {}
82
+ metadata:
83
+ rubygems_mfa_required: 'true'
83
84
  post_install_message:
84
85
  rdoc_options: []
85
86
  require_paths:
@@ -95,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
96
  - !ruby/object:Gem::Version
96
97
  version: '0'
97
98
  requirements: []
98
- rubygems_version: 3.1.2
99
+ rubygems_version: 3.3.7
99
100
  signing_key:
100
101
  specification_version: 4
101
102
  summary: Streamlined bundler audit with Changelog detection and summary ouput