gem_updater 3.0.0 → 4.0.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: 458c286b02adc73fdeac3eded5de4b65390c1bfa0374efc83651b773f96f2f7b
4
- data.tar.gz: bf55e5150ee714581df3b41e4177878c2b432d44c369d8bdd1cf62ae8f435d21
3
+ metadata.gz: aa29e2d445cbfcb39630890068aa4c500968f5c4c1765f5dbed6e3d106e04a82
4
+ data.tar.gz: 16bc9ffd31ed48f1e00e0c776472be38fc8a978aead2aebaf708f0e89b637e4b
5
5
  SHA512:
6
- metadata.gz: be83c20442e904d34c99f3674532ac80ff891e7a088abfe7f9d7867bad4c2208066ac57fd6861c508d3d47624a0f7946f72e48cb8d99abe4272e6aa3e7554287
7
- data.tar.gz: 769a8fcbbe5b19d9e9c334079e5c3a84c1fbf0d4688aace73ee33b808ee8d4fd3728247b617985694b80365715a3787768b3a24a5d9ba10c811e8bf1b0b4f692
6
+ metadata.gz: 05c074149555f10115bf97de0ecd8b98806995b45df64a0dcbb28f8bc59faae181b113a267d857f04b9f5048886abfcff90ec22fc18af92a34664de7b684aadd
7
+ data.tar.gz: 5245415abd40b10897bacd6c5df56daf1339bf1fe4cb11b4878d15e1392250e41d26f21a17e05f74dcce02f91ae2ef267e1374131747252cf349d76fea4fb789
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #!/usr/bin/env ruby
2
4
  require 'optparse'
3
5
 
4
6
  # Exit cleanly from an early interrupt
5
7
  Signal.trap('INT') { exit 1 }
6
8
 
7
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
9
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
8
10
  require 'gem_updater'
9
11
 
10
12
  Bundler.ui = Bundler::UI::Shell.new
@@ -1,12 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'memoist'
1
4
  require 'gem_updater/gem_file'
2
5
  require 'gem_updater/ruby_gems_fetcher'
3
6
  require 'gem_updater/source_page_parser'
4
7
 
8
+ # Base lib.
5
9
  module GemUpdater
6
-
7
10
  # Updater's main responsability is to fill changes
8
11
  # happened before and after update of `Gemfile`, and then format them.
9
12
  class Updater
13
+ extend Memoist
14
+
10
15
  attr_accessor :gemfile
11
16
 
12
17
  def initialize
@@ -43,23 +48,11 @@ module GemUpdater
43
48
 
44
49
  # For each gem, retrieve its changelog
45
50
  def fill_changelogs
46
- threads = []
47
-
48
- gemfile.changes.each do |gem_name, details|
49
- threads << Thread.new do
50
- if source_uri = find_source(gem_name, details[:source])
51
- source_page = GemUpdater::SourcePageParser.new(
52
- url: source_uri, version: details[:versions][:new]
53
- )
54
-
55
- if source_page.changelog
56
- gemfile.changes[gem_name][:changelog] = source_page.changelog
57
- end
58
- end
51
+ [].tap do |threads|
52
+ gemfile.changes.each do |gem_name, details|
53
+ threads << Thread.new { retrieve_gem_changes(gem_name, details) }
59
54
  end
60
- end
61
-
62
- threads.each(&:join)
55
+ end.each(&:join)
63
56
  end
64
57
 
65
58
  # Find where is hosted the source of a gem
@@ -76,16 +69,26 @@ module GemUpdater
76
69
  end
77
70
  end
78
71
 
72
+ def retrieve_gem_changes(gem_name, details)
73
+ source_uri = find_source(gem_name, details[:source])
74
+ return unless source_uri
75
+
76
+ source_page = GemUpdater::SourcePageParser.new(
77
+ url: source_uri, version: details[:versions][:new]
78
+ )
79
+
80
+ gemfile.changes[gem_name][:changelog] = source_page.changelog if source_page.changelog
81
+ end
82
+
79
83
  # Get the template for gem's diff.
80
84
  # It can use a custom template.
81
85
  #
82
86
  # @return [ERB] the template
83
87
  def template
84
- @template ||= begin
85
- File.read("#{Dir.home}/.gem_updater_template.erb")
86
- rescue Errno::ENOENT
87
- File.read(File.expand_path('../../lib/gem_updater_template.erb', __FILE__))
88
- end
88
+ File.read("#{Dir.home}/.gem_updater_template.erb")
89
+ rescue Errno::ENOENT
90
+ File.read(File.expand_path('../lib/gem_updater_template.erb', __dir__))
89
91
  end
92
+ memoize :template
90
93
  end
91
94
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/cli'
2
4
 
3
5
  module GemUpdater
4
-
5
6
  # GemFile is responsible for handling `Gemfile`
6
7
  class GemFile
7
8
  attr_accessor :changes
@@ -21,21 +22,20 @@ module GemUpdater
21
22
  #
22
23
  # @return [Hash] gems for which there are differences.
23
24
  def compute_changes
24
- get_spec_sets
25
+ spec_sets_diff!
25
26
 
26
27
  old_spec_set.each do |old_gem|
27
28
  updated_gem = new_spec_set.find { |new_gem| new_gem.name == old_gem.name }
29
+ next unless updated_gem && old_gem.version != updated_gem.version
28
30
 
29
- if updated_gem && old_gem.version != updated_gem.version
30
- fill_changes(old_gem, updated_gem)
31
- end
31
+ fill_changes(old_gem, updated_gem)
32
32
  end
33
33
  end
34
34
 
35
35
  private
36
36
 
37
37
  # Get the two spec sets (before and after `bundle update`)
38
- def get_spec_sets
38
+ def spec_sets_diff!
39
39
  @old_spec_set = spec_set
40
40
  reinitialize_spec_set!
41
41
  @new_spec_set = spec_set
@@ -1,12 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'nokogiri'
3
5
  require 'open-uri'
4
6
 
5
7
  module GemUpdater
6
-
7
8
  # RubyGemsFetcher is a wrapper around rubygems API.
8
9
  class RubyGemsFetcher
9
- HTTP_TOO_MANY_REQUESTS = '429'.freeze
10
+ HTTP_TOO_MANY_REQUESTS = '429'
10
11
  GEM_HOMEPAGES = %w[source_code_uri homepage_uri].freeze
11
12
 
12
13
  attr_reader :gem_name, :source
@@ -35,11 +36,10 @@ module GemUpdater
35
36
  def uri_from_rubygems
36
37
  return unless source.remotes.map(&:host).include?('rubygems.org')
37
38
 
38
- if response = query_rubygems
39
- response[
40
- GEM_HOMEPAGES.find { |key| response[key] && !response[key].empty? }
41
- ]
42
- end
39
+ response = query_rubygems
40
+ return unless response
41
+
42
+ response[GEM_HOMEPAGES.find { |key| response[key] && !response[key].empty? }]
43
43
  end
44
44
 
45
45
  # Make the real query to rubygems
@@ -52,7 +52,7 @@ module GemUpdater
52
52
  # We may trigger too many requests, in which case give rubygems a break
53
53
  if e.io.status.include?(HTTP_TOO_MANY_REQUESTS)
54
54
  if (tries += 1) < 2
55
- sleep 1 and retry
55
+ sleep 1 && retry
56
56
  end
57
57
  end
58
58
  end
@@ -60,6 +60,7 @@ module GemUpdater
60
60
  # Look if gem can be found in another remote
61
61
  #
62
62
  # @return [String|nil] uri of source code
63
+ # rubocop:disable Metrics/MethodLength
63
64
  def uri_from_other_sources
64
65
  uri = nil
65
66
  source.remotes.each do |remote|
@@ -70,24 +71,28 @@ module GemUpdater
70
71
  when 'rails-assets.org'
71
72
  uri_from_railsassets
72
73
  else
73
- Bundler.ui.error "Source #{remote} is not supported, feel free to open a PR or an issue on https://github.com/MaximeD/gem_updater"
74
+ Bundler.ui.error "Source #{remote} is not supported, ' \
75
+ 'feel free to open a PR or an issue on https://github.com/MaximeD/gem_updater"
74
76
  end
75
77
  end
76
78
 
77
79
  uri
78
80
  end
81
+ # rubocop:enable Metrics/MethodLength
79
82
 
80
83
  # Ask rails-assets.org for source uri of gem.
81
84
  # API is at : https://rails-assets.org/packages/package_name
82
85
  #
83
86
  # @return [String|nil] uri of source code
84
87
  def uri_from_railsassets
85
- if response = query_railsassets
86
- response['url'].gsub(/^git/, 'http')
87
- end
88
+ response = query_railsassets
89
+ return unless response
90
+
91
+ response['url'].gsub(/^git/, 'http')
88
92
  end
89
93
 
90
94
  # Make the real query to railsassets
95
+ # rubocop:disable Lint/HandleExceptions
91
96
  def query_railsassets
92
97
  JSON.parse(
93
98
  open(
@@ -99,5 +104,6 @@ module GemUpdater
99
104
  # with html (instead of json) containing a 500...
100
105
  rescue OpenURI::HTTPError
101
106
  end
107
+ # rubocop:enable Lint/HandleExceptions
102
108
  end
103
109
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
  require 'open-uri'
3
5
 
4
6
  module GemUpdater
5
-
6
7
  # SourcePageParser is responsible for parsing a source page where
7
8
  # the gem code is hosted.
8
9
  class SourcePageParser
10
+ extend Memoist
11
+
9
12
  HOSTS = {
10
13
  github: /github.com/,
11
14
  bitbucket: /bitbucket.org/,
@@ -29,23 +32,16 @@ module GemUpdater
29
32
  def changelog
30
33
  return unless uri
31
34
 
32
- @changelog ||= begin
33
- Bundler.ui.warn "Looking for a changelog in #{uri}"
34
- doc = Nokogiri::HTML(open(uri))
35
-
36
- find_changelog(doc)
37
-
38
- rescue OpenURI::HTTPError # Uri points to nothing
39
- Bundler.ui.error "Cannot find #{uri}"
40
- false
41
- rescue Errno::ETIMEDOUT # timeout
42
- Bundler.ui.error "#{uri} is down"
43
- false
44
- rescue ArgumentError => e # x-oauth-basic raises userinfo not supported. [RFC3986]
45
- Bundler.ui.error e
46
- false
47
- end
35
+ Bundler.ui.warn "Looking for a changelog in #{uri}"
36
+ find_changelog(Nokogiri::HTML(URI.open(uri)))
37
+ rescue OpenURI::HTTPError # Uri points to nothing
38
+ log_error("Cannot find #{uri}")
39
+ rescue Errno::ETIMEDOUT # timeout
40
+ log_error("#{uri} is down")
41
+ rescue ArgumentError => e # x-oauth-basic raises userinfo not supported. [RFC3986]
42
+ log_error(e)
48
43
  end
44
+ memoize :changelog
49
45
 
50
46
  private
51
47
 
@@ -55,15 +51,10 @@ module GemUpdater
55
51
  # @param url [String] the url to parse
56
52
  # @return [URI] valid URI
57
53
  def correct_uri(url)
58
- return unless String === url && !url.empty?
54
+ return unless url.is_a?(String) && !url.empty?
59
55
 
60
56
  uri = URI(url)
61
-
62
- if uri.scheme == 'http'
63
- known_https(uri)
64
- else
65
- uri
66
- end
57
+ uri.scheme == 'http' ? known_https(uri) : uri
67
58
  end
68
59
 
69
60
  # Some uris are not https, but we know they should be,
@@ -73,13 +64,13 @@ module GemUpdater
73
64
  # @param uri [URI::HTTP]
74
65
  # @return [URI::HTTPS|URI::HTTP]
75
66
  def known_https(uri)
76
- case
77
- when uri.host =~ HOSTS[:github]
67
+ case uri.host
68
+ when HOSTS[:github]
78
69
  # remove possible subdomain like 'wiki.github.com'
79
70
  URI "https://github.com#{uri.path}"
80
- when uri.host =~ HOSTS[:bitbucket]
71
+ when HOSTS[:bitbucket]
81
72
  URI "https://#{uri.host}#{uri.path}"
82
- when uri.host =~ HOSTS[:rubygems]
73
+ when HOSTS[:rubygems]
83
74
  URI "https://#{uri.host}#{uri.path}"
84
75
  else
85
76
  uri
@@ -115,10 +106,15 @@ module GemUpdater
115
106
  MARKUP_FILES.include?(File.extname(file_name))
116
107
  end
117
108
 
109
+ def log_error(error_message)
110
+ Bundler.ui.error error_message
111
+ false
112
+ end
113
+
118
114
  # GitHubParser is responsible for parsing source code
119
115
  # hosted on github.com.
120
116
  class GitHubParser < SourcePageParser
121
- BASE_URL = 'https://github.com'.freeze
117
+ BASE_URL = 'https://github.com'
122
118
 
123
119
  attr_reader :doc, :version
124
120
 
@@ -134,17 +130,16 @@ module GemUpdater
134
130
  # @return [String] the URL of changelog
135
131
  def changelog
136
132
  url = find_changelog_link
133
+ return unless url
137
134
 
138
- if url
139
- full_url = BASE_URL + url
140
-
141
- if changelog_may_contain_anchor?(full_url)
142
- anchor = find_anchor(full_url)
143
- full_url += anchor if anchor
144
- end
135
+ full_url = BASE_URL + url
145
136
 
146
- full_url
137
+ if changelog_may_contain_anchor?(full_url)
138
+ anchor = find_anchor(full_url)
139
+ full_url += anchor if anchor
147
140
  end
141
+
142
+ full_url
148
143
  end
149
144
 
150
145
  private
@@ -165,12 +160,12 @@ module GemUpdater
165
160
  # @param url [String] url of changelog
166
161
  # @return [String, nil] anchor's href
167
162
  def find_anchor(url)
168
- changelog_page = Nokogiri::HTML(open(url))
163
+ changelog_page = Nokogiri::HTML(URI.open(url))
169
164
  anchor = changelog_page.css(%(a.anchor)).find do |element|
170
165
  element.attr('href').match(version.delete('.'))
171
166
  end
172
167
 
173
- anchor.attr('href') if anchor
168
+ anchor&.attr('href')
174
169
  end
175
170
  end
176
171
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_updater
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxime Demolin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-10 00:00:00.000000000 Z
11
+ date: 2019-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - "<"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - "<"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: memoist
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.16.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.16.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: nokogiri
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '3.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.68.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.68.1
69
97
  description: Updates the gems of your Gemfile and fetches the links pointing to where
70
98
  their changelogs are
71
99
  email: akbarova.armia@gmail.com
@@ -92,15 +120,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
120
  requirements:
93
121
  - - ">="
94
122
  - !ruby/object:Gem::Version
95
- version: 2.3.0
123
+ version: 2.5.0
96
124
  required_rubygems_version: !ruby/object:Gem::Requirement
97
125
  requirements:
98
126
  - - ">="
99
127
  - !ruby/object:Gem::Version
100
128
  version: '0'
101
129
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.6
130
+ rubygems_version: 3.0.6
104
131
  signing_key:
105
132
  specification_version: 4
106
133
  summary: Update your gems and find their changelogs