gem_updater 8.2.0 → 9.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: 6b94dc6c36489685353e538c770bd45014c0f9cc102da2541e2f1587dbe4c3b2
4
- data.tar.gz: 63b776883746f78649886aa63668a43529b6fd80668f846283a929403b560644
3
+ metadata.gz: ae0b7516e382a069fe5fea921db87729ff1cd662f55a1f5e835275d82b998f42
4
+ data.tar.gz: f6b283aad770a194f12524fe6b8c243ffd1bab71c49cddab19ee6c91e04d7d69
5
5
  SHA512:
6
- metadata.gz: 844f99b0fb92dc4855cd1cf69cf7d3d6565c191f51fcb7d023f96686a9727d538a4605332b56a7d6ec92f7dad5fc4ec6dacc6ac2a373630f4d5ed8bdce8e527c
7
- data.tar.gz: 34c8ab8657ae8aeed29ab4ada671f6c867de0f1cd4aa7d5389fef2b57a8e6161c9b77e93aaa9ea85308ce7c5b9c8d161054c6e017016c3d8ff29de59ddfc9586
6
+ metadata.gz: 0ae928f0f43ddc59c3be1e76078b6c45ae12068e6c3e9a0409f47122149cc5aae81cac86bf489767fd60dc0185ad181558bc747129bd49af4c954a337f2f3388
7
+ data.tar.gz: 21044a1278e58e97905813cd1dd38185f48c68dc11112567cf16da71b079600b7e5fe86c9973306305143c25856a718cd61d0f7fb0f5e41e30f43abe4fcc1413
@@ -7,8 +7,8 @@ module GemUpdater
7
7
  class ChangelogParser
8
8
  # ChangelogParser is responsible for parsing a changelog hosted on github.
9
9
  class GithubParser
10
- REACT_DATA_XPATH = '//script[@data-target="react-app.embeddedData"]'
11
- REACT_PAYLOAD_TOC_PATH = %w[payload blob headerInfo toc].freeze
10
+ MARKDOWN_HEADING_PATTERN = /^#+\s+(.*?)$/
11
+ RDOC_HEADING_PATTERN = /^===\s+(.*?)$/
12
12
 
13
13
  attr_reader :uri, :version
14
14
 
@@ -23,33 +23,78 @@ module GemUpdater
23
23
  #
24
24
  # @return [String] the URL of changelog
25
25
  def changelog
26
- uri + find_anchor(document).to_s
26
+ anchor = find_anchor_from_raw_content
27
+ anchor ? "#{uri}##{anchor}" : uri
27
28
  end
28
29
 
29
30
  private
30
31
 
31
- # Opens changelog url and parses it.
32
+ # Fetches raw markdown/RDoc content and finds anchor for the version
32
33
  #
33
- # @return [Nokogiri::HTML4::Document] the changelog
34
- def document
35
- Nokogiri::HTML(URI.parse(uri).open, nil, Encoding::UTF_8.to_s)
34
+ # @return [String, nil] anchor if found
35
+ def find_anchor_from_raw_content
36
+ raw_url = raw_content_url
37
+ return unless raw_url
38
+
39
+ begin
40
+ content = URI.parse(raw_url).read
41
+ parse_headings(content)
42
+ rescue OpenURI::HTTPError
43
+ nil
44
+ end
45
+ end
46
+
47
+ # Extracts raw content URL from GitHub's X-Raw-Download response header
48
+ #
49
+ # @return [String] raw content URL
50
+ def raw_content_url
51
+ response = URI.parse(uri).open
52
+ response.meta['x-raw-download']
36
53
  end
37
54
 
38
- # Looks into document to find it there is an anchor to new gem version.
55
+ # Parses markdown/RDoc content to find heading matching the version
39
56
  #
40
- # @param doc [Nokogiri::HTML4::Document] document
41
- # @return [String, nil] anchor's href
42
- def find_anchor(doc)
43
- react_data = doc.at_xpath(REACT_DATA_XPATH)
44
- return unless react_data
45
-
46
- react_content = JSON.parse(react_data.text)
47
- anchor = react_content
48
- .dig(*REACT_PAYLOAD_TOC_PATH).to_a
49
- .find { |item| item['text'].match(version) }&.[]('anchor')
50
- return unless anchor
51
-
52
- "##{anchor}"
57
+ # @param content [String] raw markdown/RDoc content
58
+ # @return [String, nil] anchor if found
59
+ def parse_headings(content)
60
+ heading_patterns = [MARKDOWN_HEADING_PATTERN, RDOC_HEADING_PATTERN]
61
+
62
+ content.each_line do |line|
63
+ heading_text = heading_patterns.each do |pattern|
64
+ break Regexp.last_match(1).strip if line.match(pattern)
65
+ end
66
+ heading_text = nil if heading_text.is_a?(Array)
67
+
68
+ next unless heading_text&.match?(version)
69
+
70
+ return generate_github_anchor(heading_text)
71
+ end
72
+ nil
73
+ end
74
+
75
+ # Generates GitHub-style anchor from heading text
76
+ #
77
+ # @param heading_text [String] the heading text
78
+ # @return [String] GitHub-style anchor
79
+ def generate_github_anchor(heading_text)
80
+ # GitHub's anchor generation algorithm:
81
+ # 1. Convert to lowercase
82
+ # 2. Remove dots
83
+ # 3. Replace / with --
84
+ # 4. Replace em dashes with ---
85
+ # 5. Remove special characters except letters (including accented), numbers, hyphens, spaces
86
+ # 6. Replace spaces with hyphens
87
+ # 7. Remove leading/trailing hyphens
88
+ anchor = heading_text
89
+ .downcase
90
+ .delete('.')
91
+ .gsub(%r{\s*/\s*}, '--')
92
+ .gsub(/—/, '---') # Replace em dash with three hyphens
93
+ .gsub(/[^\p{L}0-9\-\s]/, '') # Keep all Unicode letters including accented
94
+ .gsub(/\s+/, '-')
95
+ .sub(/^-|-$/, '')
96
+
97
+ anchor.empty? ? nil : anchor
53
98
  end
54
99
  end
55
100
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemUpdater
4
- VERSION = '8.2.0'
4
+ VERSION = '9.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_updater
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.2.0
4
+ version: 9.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxime Demolin
@@ -166,14 +166,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
166
  requirements:
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
- version: '3.2'
169
+ version: '3.3'
170
170
  required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  requirements:
172
172
  - - ">="
173
173
  - !ruby/object:Gem::Version
174
174
  version: '0'
175
175
  requirements: []
176
- rubygems_version: 4.0.3
176
+ rubygems_version: 4.0.6
177
177
  specification_version: 4
178
178
  summary: Update your gems and find their changelogs
179
179
  test_files: []