gem_updater 3.0.0 → 4.0.0

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: 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