gem_updater 6.0.2 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gem_updater/changelog_parser/github_parser.rb +49 -0
- data/lib/gem_updater/changelog_parser.rb +64 -0
- data/lib/gem_updater/{gem_file.rb → gemfile.rb} +2 -2
- data/lib/gem_updater/ruby_gems_fetcher.rb +9 -61
- data/lib/gem_updater/version.rb +1 -1
- data/lib/gem_updater.rb +14 -28
- metadata +8 -18
- data/lib/gem_updater/source_page_parser.rb +0 -173
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc62f5f20f9d239d4eea066d409fd9900ba139630287a2884fe2497c09ce91e7
|
4
|
+
data.tar.gz: 0dc7e3a0446c91dc1a9d24786f381623a162f95218ce1e212d701768f2f99082
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7d95be3b9d660ea9af8b2b469e49613305230b6431a4c5c0ea351e49192b035546ff0da342c904062a0518fcc1c1b2327462c4380eed69b9fe189b32fa28b9f
|
7
|
+
data.tar.gz: 722d4d3924adb67a00b844c517da2b664685a23a0ebd4964e5bf3e16fc7f4fd69ce20ee79b7c905455bef6a511b1759dc4aa6382391a99fa55b15a0bc2180825
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
module GemUpdater
|
7
|
+
class ChangelogParser
|
8
|
+
# ChangelogParser is responsible for parsing a changelog hosted on github.
|
9
|
+
class GithubParser
|
10
|
+
attr_reader :uri, :version
|
11
|
+
|
12
|
+
# @param uri [String] changelog uri
|
13
|
+
# @param version [String] version of gem
|
14
|
+
def initialize(uri:, version:)
|
15
|
+
@uri = uri
|
16
|
+
@version = version
|
17
|
+
end
|
18
|
+
|
19
|
+
# Finds anchor in changelog, otherwise return the base uri.
|
20
|
+
#
|
21
|
+
# @return [String] the URL of changelog
|
22
|
+
def changelog
|
23
|
+
uri + find_anchor(document).to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Opens changelog url and parses it.
|
29
|
+
#
|
30
|
+
# @return [Nokogiri::HTML4::Document] the changelog
|
31
|
+
def document
|
32
|
+
Nokogiri::HTML(URI.parse(uri).open, nil, Encoding::UTF_8.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Looks into document to find it there is an anchor to new gem version.
|
36
|
+
#
|
37
|
+
# @param doc [Nokogiri::HTML4::Document] document
|
38
|
+
# @return [String, nil] anchor's href
|
39
|
+
def find_anchor(doc)
|
40
|
+
anchor = doc.xpath('//a[contains(@class, "heading-link")]').find do |element|
|
41
|
+
element.attr('href').match(version.delete('.'))
|
42
|
+
end
|
43
|
+
return unless anchor
|
44
|
+
|
45
|
+
anchor.attr('href').gsub(%(\\"), '')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'gem_updater/changelog_parser/github_parser'
|
6
|
+
|
7
|
+
module GemUpdater
|
8
|
+
# ChangelogParser is responsible for parsing a source page where
|
9
|
+
# the gem code is hosted.
|
10
|
+
class ChangelogParser
|
11
|
+
MARKUP_FILES = %w[.md .rdoc .textile].freeze
|
12
|
+
|
13
|
+
attr_reader :uri, :version
|
14
|
+
|
15
|
+
# @param uri [String] uri of changelog
|
16
|
+
# @param version [String] version of gem
|
17
|
+
def initialize(uri:, version:)
|
18
|
+
@uri = uri
|
19
|
+
@version = version
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the changelog in an uri.
|
23
|
+
#
|
24
|
+
# @return [String, nil] URL of changelog
|
25
|
+
def changelog
|
26
|
+
return uri unless changelog_may_contain_anchor?
|
27
|
+
|
28
|
+
parse_changelog
|
29
|
+
rescue OpenURI::HTTPError # Uri points to nothing
|
30
|
+
log_error_and_return_uri("Cannot find #{uri}")
|
31
|
+
rescue Errno::ETIMEDOUT # timeout
|
32
|
+
log_error_and_return_uri("#{URI.parse(uri).host} is down")
|
33
|
+
rescue ArgumentError => e # x-oauth-basic raises userinfo not supported. [RFC3986]
|
34
|
+
log_error_and_return_uri(e)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Try to find where changelog might be.
|
40
|
+
#
|
41
|
+
# @param doc [Nokogiri::XML::Element] document of source page
|
42
|
+
def parse_changelog
|
43
|
+
case URI.parse(uri).host
|
44
|
+
when 'github.com'
|
45
|
+
GithubParser.new(uri: uri, version: version).changelog
|
46
|
+
else
|
47
|
+
uri
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Some documents like the one written in markdown may contain
|
52
|
+
# a direct anchor to specific version.
|
53
|
+
#
|
54
|
+
# @return [Boolean] true if file may contain an anchor
|
55
|
+
def changelog_may_contain_anchor?
|
56
|
+
MARKUP_FILES.include?(File.extname(uri.to_s))
|
57
|
+
end
|
58
|
+
|
59
|
+
def log_error_and_return_uri(error_message)
|
60
|
+
Bundler.ui.error error_message
|
61
|
+
uri
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -4,8 +4,8 @@ require 'bundler'
|
|
4
4
|
require 'bundler/cli'
|
5
5
|
|
6
6
|
module GemUpdater
|
7
|
-
#
|
8
|
-
class
|
7
|
+
# Gemfile is responsible for handling `Gemfile`
|
8
|
+
class Gemfile
|
9
9
|
attr_accessor :changes
|
10
10
|
attr_reader :old_spec_set, :new_spec_set
|
11
11
|
|
@@ -8,23 +8,22 @@ module GemUpdater
|
|
8
8
|
# RubyGemsFetcher is a wrapper around rubygems API.
|
9
9
|
class RubyGemsFetcher
|
10
10
|
HTTP_TOO_MANY_REQUESTS = '429'
|
11
|
-
GEM_HOMEPAGES = %w[source_code_uri homepage_uri].freeze
|
12
11
|
|
13
|
-
attr_reader :gem_name
|
12
|
+
attr_reader :gem_name
|
14
13
|
|
15
14
|
# @param gem_name [String] name of the gem
|
16
|
-
|
17
|
-
def initialize(gem_name, source)
|
15
|
+
def initialize(gem_name)
|
18
16
|
@gem_name = gem_name
|
19
|
-
@source = source
|
20
17
|
end
|
21
18
|
|
22
|
-
# Finds
|
23
|
-
#
|
19
|
+
# Finds the changelog uri.
|
20
|
+
# It asks rubygems.org for changelog_uri of gem.
|
21
|
+
# See API: http://guides.rubygems.org/rubygems-org-api/#gem-methods
|
24
22
|
#
|
25
|
-
# @return [String|nil]
|
26
|
-
def
|
27
|
-
|
23
|
+
# @return [String|nil] uri of changelog
|
24
|
+
def changelog_uri
|
25
|
+
response = query_rubygems
|
26
|
+
response.to_h['changelog_uri']
|
28
27
|
end
|
29
28
|
|
30
29
|
private
|
@@ -37,19 +36,6 @@ module GemUpdater
|
|
37
36
|
JSON.parse(URI.parse(url).open.read)
|
38
37
|
end
|
39
38
|
|
40
|
-
# Ask rubygems.org for source uri of gem.
|
41
|
-
# See API: http://guides.rubygems.org/rubygems-org-api/#gem-methods
|
42
|
-
#
|
43
|
-
# @return [String|nil] uri of source code
|
44
|
-
def uri_from_rubygems
|
45
|
-
return unless source.remotes.map(&:host).include?('rubygems.org')
|
46
|
-
|
47
|
-
response = query_rubygems
|
48
|
-
return unless response
|
49
|
-
|
50
|
-
response[GEM_HOMEPAGES.find { |key| response[key] && !response[key].empty? }]
|
51
|
-
end
|
52
|
-
|
53
39
|
# Make the real query to rubygems
|
54
40
|
# It may fail in case we trigger too many requests
|
55
41
|
#
|
@@ -63,43 +49,5 @@ module GemUpdater
|
|
63
49
|
sleep 1 && retry if tries < 2
|
64
50
|
end
|
65
51
|
end
|
66
|
-
|
67
|
-
# Look if gem can be found in another remote
|
68
|
-
#
|
69
|
-
# @return [String|nil] uri of source code
|
70
|
-
def uri_from_other_sources
|
71
|
-
source.remotes.find do |remote|
|
72
|
-
case remote.host
|
73
|
-
when 'rubygems.org' then next # already checked
|
74
|
-
when 'rails-assets.org'
|
75
|
-
return uri_from_railsassets
|
76
|
-
else
|
77
|
-
Bundler.ui.error "Source #{remote} is not supported, ' \
|
78
|
-
'feel free to open a PR or an issue on https://github.com/MaximeD/gem_updater"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Ask rails-assets.org for source uri of gem.
|
84
|
-
# API is at : https://rails-assets.org/packages/package_name
|
85
|
-
#
|
86
|
-
# @return [String|nil] uri of source code
|
87
|
-
def uri_from_railsassets
|
88
|
-
response = query_railsassets
|
89
|
-
return unless response
|
90
|
-
|
91
|
-
response['url'].gsub(/^git/, 'http')
|
92
|
-
end
|
93
|
-
|
94
|
-
# Make the real query to railsassets
|
95
|
-
# rubocop:disable Lint/SuppressedException
|
96
|
-
def query_railsassets
|
97
|
-
parse_remote_json("https://rails-assets.org/packages/#{gem_name.gsub('rails-assets-', '')}")
|
98
|
-
rescue JSON::ParserError
|
99
|
-
# if gem is not found, rails-assets returns a 200
|
100
|
-
# with html (instead of json) containing a 500...
|
101
|
-
rescue OpenURI::HTTPError
|
102
|
-
end
|
103
|
-
# rubocop:enable Lint/SuppressedException
|
104
52
|
end
|
105
53
|
end
|
data/lib/gem_updater/version.rb
CHANGED
data/lib/gem_updater.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'erb'
|
4
|
-
require '
|
5
|
-
require 'gem_updater/
|
4
|
+
require 'gem_updater/changelog_parser'
|
5
|
+
require 'gem_updater/gemfile'
|
6
6
|
require 'gem_updater/ruby_gems_fetcher'
|
7
|
-
require 'gem_updater/source_page_parser'
|
8
7
|
|
9
8
|
# Base lib.
|
10
9
|
module GemUpdater
|
11
10
|
# Updater's main responsability is to fill changes
|
12
11
|
# happened before and after update of `Gemfile`, and then format them.
|
13
12
|
class Updater
|
14
|
-
|
13
|
+
RUBYGEMS_SOURCE_NAME = 'rubygems repository https://rubygems.org/'
|
15
14
|
|
16
15
|
attr_accessor :gemfile
|
17
16
|
|
18
17
|
def initialize
|
19
|
-
@gemfile = GemUpdater::
|
18
|
+
@gemfile = GemUpdater::Gemfile.new
|
20
19
|
end
|
21
20
|
|
22
21
|
# Update process.
|
@@ -52,35 +51,23 @@ module GemUpdater
|
|
52
51
|
# For each gem, retrieve its changelog
|
53
52
|
def fill_changelogs
|
54
53
|
[].tap do |threads|
|
55
|
-
gemfile.changes.each do |
|
56
|
-
threads << Thread.new {
|
54
|
+
gemfile.changes.each do |gem_changes, details|
|
55
|
+
threads << Thread.new { retrieve_changelog(gem_changes, details) }
|
57
56
|
end
|
58
57
|
end.each(&:join)
|
59
58
|
end
|
60
59
|
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
# @param source [Bundler::Source] gem's source
|
65
|
-
# @return [String] url where gem is hosted
|
66
|
-
def find_source(gem, source)
|
67
|
-
case source
|
68
|
-
when Bundler::Source::Rubygems
|
69
|
-
GemUpdater::RubyGemsFetcher.new(gem, source).source_uri
|
70
|
-
when Bundler::Source::Git
|
71
|
-
source.uri.gsub(/^git/, 'http').chomp('.git')
|
72
|
-
end
|
73
|
-
end
|
60
|
+
# Get the changelog URL.
|
61
|
+
def retrieve_changelog(gem_name, details)
|
62
|
+
return unless details[:source].name == RUBYGEMS_SOURCE_NAME
|
74
63
|
|
75
|
-
|
76
|
-
source_uri = find_source(gem_name, details[:source])
|
77
|
-
return unless source_uri
|
64
|
+
changelog_uri = RubyGemsFetcher.new(gem_name).changelog_uri
|
78
65
|
|
79
|
-
|
80
|
-
url: source_uri, version: details[:versions][:new]
|
81
|
-
)
|
66
|
+
return unless changelog_uri
|
82
67
|
|
83
|
-
|
68
|
+
changelog = ChangelogParser
|
69
|
+
.new(uri: changelog_uri, version: details.dig(:versions, :new)).changelog
|
70
|
+
gemfile.changes[gem_name][:changelog] = changelog&.to_s
|
84
71
|
end
|
85
72
|
|
86
73
|
# Get the template for gem's diff.
|
@@ -92,6 +79,5 @@ module GemUpdater
|
|
92
79
|
rescue Errno::ENOENT
|
93
80
|
File.read(File.expand_path('../lib/gem_updater_template.erb', __dir__))
|
94
81
|
end
|
95
|
-
memoize :template
|
96
82
|
end
|
97
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem_updater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.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: 2023-
|
11
|
+
date: 2023-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.6'
|
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.2
|
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.2
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: nokogiri
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,15 +146,19 @@ extra_rdoc_files: []
|
|
160
146
|
files:
|
161
147
|
- bin/gem_update
|
162
148
|
- lib/gem_updater.rb
|
163
|
-
- lib/gem_updater/
|
149
|
+
- lib/gem_updater/changelog_parser.rb
|
150
|
+
- lib/gem_updater/changelog_parser/github_parser.rb
|
151
|
+
- lib/gem_updater/gemfile.rb
|
164
152
|
- lib/gem_updater/ruby_gems_fetcher.rb
|
165
|
-
- lib/gem_updater/source_page_parser.rb
|
166
153
|
- lib/gem_updater/version.rb
|
167
154
|
- lib/gem_updater_template.erb
|
168
155
|
homepage: https://github.com/MaximeD/gem_updater
|
169
156
|
licenses:
|
170
157
|
- MIT
|
171
158
|
metadata:
|
159
|
+
homepage_uri: https://github.com/MaximeD/gem_updater
|
160
|
+
changelog_uri: https://github.com/MaximeD/gem_updater/blob/master/CHANGELOG.md
|
161
|
+
source_code_uri: https://github.com/MaximeD/gem_updater
|
172
162
|
rubygems_mfa_required: 'true'
|
173
163
|
post_install_message:
|
174
164
|
rdoc_options: []
|
@@ -1,173 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'open-uri'
|
5
|
-
|
6
|
-
module GemUpdater
|
7
|
-
# SourcePageParser is responsible for parsing a source page where
|
8
|
-
# the gem code is hosted.
|
9
|
-
class SourcePageParser
|
10
|
-
extend Memoist
|
11
|
-
|
12
|
-
HOSTS = {
|
13
|
-
github: /github.com/,
|
14
|
-
bitbucket: /bitbucket.org/,
|
15
|
-
rubygems: /rubygems.org/
|
16
|
-
}.freeze
|
17
|
-
MARKUP_FILES = %w[.md .rdoc .textile].freeze
|
18
|
-
CHANGELOG_NAMES = %w[changelog ChangeLog history changes news].freeze
|
19
|
-
|
20
|
-
attr_reader :uri, :version
|
21
|
-
|
22
|
-
# @param url [String] url of page
|
23
|
-
# @param version [String] version of gem
|
24
|
-
def initialize(url: nil, version: nil)
|
25
|
-
@uri = correct_uri(url)
|
26
|
-
@version = version
|
27
|
-
end
|
28
|
-
|
29
|
-
# Get the changelog in an uri.
|
30
|
-
#
|
31
|
-
# @return [String, nil] URL of changelog
|
32
|
-
def changelog
|
33
|
-
return unless uri
|
34
|
-
|
35
|
-
Bundler.ui.warn "Looking for a changelog in #{uri}"
|
36
|
-
find_changelog(Nokogiri::HTML(uri.open))
|
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)
|
43
|
-
end
|
44
|
-
memoize :changelog
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# Some gems have 'http://github.com' as URI which will redirect to https
|
49
|
-
# leading `open_uri` to crash.
|
50
|
-
#
|
51
|
-
# @param url [String] the url to parse
|
52
|
-
# @return [URI] valid URI
|
53
|
-
def correct_uri(url)
|
54
|
-
return unless url.is_a?(String) && !url.empty?
|
55
|
-
|
56
|
-
uri = URI.parse(url)
|
57
|
-
uri.scheme == 'http' ? known_https(uri) : uri
|
58
|
-
end
|
59
|
-
|
60
|
-
# Some uris are not https, but we know they should be,
|
61
|
-
# in which case we have an https redirection
|
62
|
-
# which is not properly handled by open-uri
|
63
|
-
#
|
64
|
-
# @param uri [URI::HTTP]
|
65
|
-
# @return [URI::HTTPS|URI::HTTP]
|
66
|
-
def known_https(uri)
|
67
|
-
case uri.host
|
68
|
-
when HOSTS[:github]
|
69
|
-
# remove possible subdomain like 'wiki.github.com'
|
70
|
-
URI "https://github.com#{uri.path}"
|
71
|
-
when HOSTS[:bitbucket], HOSTS[:rubygems]
|
72
|
-
URI "https://#{uri.host}#{uri.path}"
|
73
|
-
else
|
74
|
-
uri
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Try to find where changelog might be.
|
79
|
-
#
|
80
|
-
# @param doc [Nokogiri::XML::Element] document of source page
|
81
|
-
def find_changelog(doc)
|
82
|
-
case uri.host
|
83
|
-
when 'github.com'
|
84
|
-
GitHubParser.new(doc, version).changelog
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# List possible names for a changelog
|
89
|
-
# since humans may have many many ways to call it.
|
90
|
-
#
|
91
|
-
# @return [Array] list of possible names
|
92
|
-
def changelog_names
|
93
|
-
CHANGELOG_NAMES.flat_map do |name|
|
94
|
-
[name, name.upcase, name.capitalize]
|
95
|
-
end.uniq
|
96
|
-
end
|
97
|
-
|
98
|
-
# Some documents like the one written in markdown may contain
|
99
|
-
# a direct anchor to specific version.
|
100
|
-
#
|
101
|
-
# @param file_name [String] file name of changelog
|
102
|
-
# @return [Boolean] true if file may contain an anchor
|
103
|
-
def changelog_may_contain_anchor?(file_name)
|
104
|
-
MARKUP_FILES.include?(File.extname(file_name))
|
105
|
-
end
|
106
|
-
|
107
|
-
def log_error(error_message)
|
108
|
-
Bundler.ui.error error_message
|
109
|
-
false
|
110
|
-
end
|
111
|
-
|
112
|
-
# GitHubParser is responsible for parsing source code
|
113
|
-
# hosted on github.com.
|
114
|
-
class GitHubParser < SourcePageParser
|
115
|
-
BASE_URL = 'https://github.com'
|
116
|
-
|
117
|
-
attr_reader :doc, :version
|
118
|
-
|
119
|
-
# @param doc [Nokogiri::XML::Element] document of source page
|
120
|
-
# @param version [String] version of gem
|
121
|
-
# rubocop:disable Lint/MissingSuper
|
122
|
-
def initialize(doc, version)
|
123
|
-
@doc = doc
|
124
|
-
@version = version
|
125
|
-
end
|
126
|
-
# rubocop:enable Lint/MissingSuper
|
127
|
-
|
128
|
-
# Finds url of changelog.
|
129
|
-
#
|
130
|
-
# @return [String] the URL of changelog
|
131
|
-
def changelog
|
132
|
-
url = find_changelog_link
|
133
|
-
return unless url
|
134
|
-
|
135
|
-
full_url = BASE_URL + url
|
136
|
-
|
137
|
-
if changelog_may_contain_anchor?(full_url)
|
138
|
-
anchor = find_anchor(full_url)
|
139
|
-
full_url += anchor if anchor
|
140
|
-
end
|
141
|
-
|
142
|
-
full_url
|
143
|
-
end
|
144
|
-
|
145
|
-
private
|
146
|
-
|
147
|
-
# Find which link corresponds to changelog.
|
148
|
-
# Last one is taken as files come after directories. So if there is a directory plus a file
|
149
|
-
# matching a changelog name, we ensure file is preferred.
|
150
|
-
#
|
151
|
-
# @return [String, nil] url of changelog
|
152
|
-
def find_changelog_link
|
153
|
-
changelog_names.filter_map do |name|
|
154
|
-
doc.at_css(%([aria-labelledby="files"] a[title^="#{name}"]))
|
155
|
-
end.last&.attr('href')
|
156
|
-
end
|
157
|
-
|
158
|
-
# Looks into document to find it there is an anchor to new gem version.
|
159
|
-
#
|
160
|
-
# @param url [String] url of changelog
|
161
|
-
# @return [String, nil] anchor's href
|
162
|
-
def find_anchor(url)
|
163
|
-
changelog_page = Nokogiri::HTML(URI.parse(url).open)
|
164
|
-
anchor = changelog_page.xpath('//a[contains(@class, "anchor")]').find do |element|
|
165
|
-
element.attr('href').match(version.delete('.'))
|
166
|
-
end
|
167
|
-
return unless anchor
|
168
|
-
|
169
|
-
anchor.attr('href').gsub(%(\\"), '')
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|