bundle_update_interactive 0.2.1 → 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: 24de9c6dde2b3514ffad21a64256359200e2bb717b1a0385caa8d032776d5fe6
4
- data.tar.gz: 4a1a1c65bd89e4c7e17d563c2a854c80e07edeb7d04e6b4ffdf3cbef1d47ddee
3
+ metadata.gz: 0bdc9b0322d61da7334ee24e12d415948f8f1117f6824ebb4afe5eec6eadd57e
4
+ data.tar.gz: bdc4cf0e7a740c4f33f9211b269257cc854ba49f9d190f956dcdb2513cbfef6b
5
5
  SHA512:
6
- metadata.gz: 493421b5621ff128b56ed96041fd4c1e776de8c0160f330d8458d40963248e2c2e779dc64c7f7afd390c2f98d62a6203b3495534e7b57051f79add6edc729715
7
- data.tar.gz: 638b235f21664177f8b9de29a0b69b9229ef1b57fc985c4ba6c73678ca2142a926caff18626a809b4ab4fdd2aeff4573e7a4137c471ca569d62b95e55322e0ec
6
+ metadata.gz: 6120695a0dcd0f21cc652e3e37a7b3f2a1573bfc042aba435d97896522cfd92a169c7d66cc73f7bbd2b4e5d8244b37321acda4e42ca61092201f80c584c65552
7
+ data.tar.gz: 37b171778494c7e5e8b89f16f6c9b0c6e47a22d2c3dc174c7d80e0324dac1a36260a485cc220aa7746d43db757917a8eb11df8dac312e6bee2048f5d0fb56371
data/README.md CHANGED
@@ -75,17 +75,17 @@ If you discover a gem that is missing a changelog in `bundle update-interactive`
75
75
 
76
76
  ### Git diffs
77
77
 
78
- If your `Gemfile` sources a gem from a GitHub repo like this:
78
+ If your `Gemfile` sources a gem from a Git repo like this:
79
79
 
80
80
  ```ruby
81
81
  gem "rails", github: "rails/rails", branch: "7-1-stable"
82
82
  ```
83
83
 
84
- Then `bundle update-interactive` will show a GitHub diff link instead of a changelog, so you can see exactly what changed when the gem is updated. For example:
84
+ Then `bundle update-interactive` will show a diff link instead of a changelog, so you can see exactly what changed when the gem is updated. For example:
85
85
 
86
86
  https://github.com/rails/rails/compare/5a8d894...77dfa65
87
87
 
88
- Currently only GitHub repos are supported, but I'm considering adding GitLab and BitBucket as well.
88
+ This feature currently works for GitHub, GitLab, and Bitbucket repos.
89
89
 
90
90
  ### Conservative updates
91
91
 
@@ -10,48 +10,72 @@ EXT_PATTERN = /md|txt|rdoc/i.freeze
10
10
 
11
11
  module BundleUpdateInteractive
12
12
  class ChangelogLocator
13
- # TODO: refactor
14
- def find_changelog_uri(name:, version: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
15
- if version
16
- response = Faraday.get("https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}.json")
17
- version = nil unless response.success?
13
+ class GitHubRepo
14
+ def self.from_uris(*uris)
15
+ uris.flatten.each do |uri|
16
+ return new(Regexp.last_match(1)) if uri&.match(GITHUB_PATTERN)
17
+ end
18
+ nil
18
19
  end
19
20
 
20
- response = Faraday.get("https://rubygems.org/api/v1/gems/#{name}.json") if version.nil?
21
+ attr_reader :path
21
22
 
22
- return nil unless response.success?
23
+ def initialize(path)
24
+ @path = path
25
+ end
23
26
 
24
- data = JSON.parse(response.body)
27
+ def discover_changelog_uri(version)
28
+ repo_html = fetch_repo_html(follow_redirect: true)
29
+ return if repo_html.nil?
25
30
 
26
- version ||= data["version"]
27
- changelog_uri = data["changelog_uri"]
28
- github_repo = guess_github_repo(data)
31
+ changelog_path = repo_html[%r{/(#{path}/blob/[^/]+/#{FILE_PATTERN}(?:\.#{EXT_PATTERN})?)"}i, 1]
32
+ return "https://github.com/#{changelog_path}" if changelog_path
29
33
 
30
- if changelog_uri.nil? && github_repo
31
- file_list = Faraday.get("https://github.com/#{github_repo}")
32
- if file_list.status == 301
33
- github_repo = file_list.headers["Location"][GITHUB_PATTERN, 1]
34
- file_list = Faraday.get(file_list.headers["Location"])
35
- end
36
- match = file_list.body.match(%r{/(#{github_repo}/blob/[^/]+/#{FILE_PATTERN}(?:\.#{EXT_PATTERN})?)"}i)
37
- changelog_uri = "https://github.com/#{match[1]}" if match
34
+ releases_url = "https://github.com/#{path}/releases"
35
+ releases_url if Faraday.head("#{releases_url}/tag/v#{version}").success?
38
36
  end
39
37
 
40
- if changelog_uri.nil? && github_repo
41
- releases_uri = "https://github.com/#{github_repo}/releases"
42
- changelog_uri = releases_uri if Faraday.head("#{releases_uri}/tag/v#{version}").success?
38
+ private
39
+
40
+ def fetch_repo_html(follow_redirect:)
41
+ response = Faraday.get("https://github.com/#{path}")
42
+
43
+ if response.status == 301 && follow_redirect
44
+ @path = response.headers["Location"][GITHUB_PATTERN, 1]
45
+ return fetch_repo_html(follow_redirect: false)
46
+ end
47
+
48
+ response.success? ? response.body : nil
43
49
  end
50
+ end
51
+
52
+ def find_changelog_uri(name:, version: nil)
53
+ data = fetch_rubygems_data(name, version)
54
+ return if data.nil?
44
55
 
45
- changelog_uri
56
+ if (rubygems_changelog_uri = data["changelog_uri"])
57
+ rubygems_changelog_uri
58
+ elsif (github_repo = GitHubRepo.from_uris(data.values_at(*URI_KEYS)))
59
+ github_repo.discover_changelog_uri(data["version"])
60
+ end
46
61
  end
47
62
 
48
63
  private
49
64
 
50
- def guess_github_repo(data)
51
- data.values_at(*URI_KEYS).each do |uri|
52
- return Regexp.last_match(1) if uri&.match(GITHUB_PATTERN)
53
- end
54
- nil
65
+ def fetch_rubygems_data(name, version)
66
+ api_url = if version.nil?
67
+ "https://rubygems.org/api/v1/gems/#{name}.json"
68
+ else
69
+ "https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}.json"
70
+ end
71
+
72
+ response = Faraday.get(api_url)
73
+
74
+ # Try again without the version in case the version does not exist at rubygems for some reason.
75
+ # This can happen when using a pre-release Ruby that has a bundled gem newer than the published version.
76
+ return fetch_rubygems_data(name, nil) if !response.success? && !version.nil?
77
+
78
+ response.success? ? JSON.parse(response.body) : nil
55
79
  end
56
80
  end
57
81
  end
@@ -35,8 +35,8 @@ module BundleUpdateInteractive
35
35
  return @changelog_uri if defined?(@changelog_uri)
36
36
 
37
37
  @changelog_uri =
38
- if git_version_changed? && github_repo
39
- "https://github.com/#{github_repo}/compare/#{current_git_version}...#{updated_git_version}"
38
+ if (diff_url = build_git_diff_url)
39
+ diff_url
40
40
  elsif rubygems_source?
41
41
  changelog_locator.find_changelog_uri(name: name, version: updated_version.to_s)
42
42
  else
@@ -56,10 +56,34 @@ module BundleUpdateInteractive
56
56
 
57
57
  attr_reader :changelog_locator
58
58
 
59
+ def build_git_diff_url
60
+ return nil unless git_version_changed?
61
+
62
+ if github_repo
63
+ "https://github.com/#{github_repo}/compare/#{current_git_version}...#{updated_git_version}"
64
+ elsif gitlab_repo
65
+ "https://gitlab.com/os85/httpx/-/compare/#{current_git_version}...#{updated_git_version}"
66
+ elsif bitbucket_cloud_repo
67
+ "https://bitbucket.org/#{bitbucket_cloud_repo}/branches/compare/#{updated_git_version}..#{current_git_version}"
68
+ end
69
+ end
70
+
59
71
  def github_repo
60
72
  return nil unless updated_git_version
61
73
 
62
74
  git_source_uri.to_s[%r{^(?:git@github.com:|https://github.com/)([^/]+/[^/]+?)(:?\.git)?(?:$|/)}i, 1]
63
75
  end
76
+
77
+ def gitlab_repo
78
+ return nil unless updated_git_version
79
+
80
+ git_source_uri.to_s[%r{^(?:git@gitlab.com:|https://gitlab.com/)([^/]+/[^/]+?)(:?\.git)?(?:$|/)}i, 1]
81
+ end
82
+
83
+ def bitbucket_cloud_repo
84
+ return nil unless updated_git_version
85
+
86
+ git_source_uri.to_s[%r{(?:@|://)bitbucket.org[:/]([^/]+/[^/]+?)(:?\.git)?(?:$|/)}i, 1]
87
+ end
64
88
  end
65
89
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BundleUpdateInteractive
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundle_update_interactive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-17 00:00:00.000000000 Z
11
+ date: 2024-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler