dependabot-core 0.93.17 → 0.94.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/dependabot/dependency.rb +16 -21
  4. data/lib/dependabot/file_fetchers.rb +1 -5
  5. data/lib/dependabot/file_parsers.rb +1 -5
  6. data/lib/dependabot/file_updaters.rb +1 -5
  7. data/lib/dependabot/metadata_finders.rb +1 -5
  8. data/lib/dependabot/pull_request_creator/labeler.rb +26 -24
  9. data/lib/dependabot/update_checkers.rb +1 -5
  10. data/lib/dependabot/utils.rb +2 -12
  11. data/lib/dependabot/version.rb +1 -1
  12. metadata +1 -28
  13. data/lib/dependabot/file_fetchers/ruby/bundler.rb +0 -215
  14. data/lib/dependabot/file_fetchers/ruby/bundler/child_gemfile_finder.rb +0 -70
  15. data/lib/dependabot/file_fetchers/ruby/bundler/gemspec_finder.rb +0 -98
  16. data/lib/dependabot/file_fetchers/ruby/bundler/path_gemspec_finder.rb +0 -114
  17. data/lib/dependabot/file_fetchers/ruby/bundler/require_relative_finder.rb +0 -67
  18. data/lib/dependabot/file_parsers/ruby/bundler.rb +0 -294
  19. data/lib/dependabot/file_parsers/ruby/bundler/file_preparer.rb +0 -86
  20. data/lib/dependabot/file_parsers/ruby/bundler/gemfile_checker.rb +0 -48
  21. data/lib/dependabot/file_updaters/ruby/bundler.rb +0 -123
  22. data/lib/dependabot/file_updaters/ruby/bundler/gemfile_updater.rb +0 -116
  23. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_dependency_name_finder.rb +0 -52
  24. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_sanitizer.rb +0 -298
  25. data/lib/dependabot/file_updaters/ruby/bundler/gemspec_updater.rb +0 -64
  26. data/lib/dependabot/file_updaters/ruby/bundler/git_pin_replacer.rb +0 -80
  27. data/lib/dependabot/file_updaters/ruby/bundler/git_source_remover.rb +0 -102
  28. data/lib/dependabot/file_updaters/ruby/bundler/lockfile_updater.rb +0 -389
  29. data/lib/dependabot/file_updaters/ruby/bundler/requirement_replacer.rb +0 -223
  30. data/lib/dependabot/metadata_finders/ruby/bundler.rb +0 -202
  31. data/lib/dependabot/update_checkers/ruby/bundler.rb +0 -331
  32. data/lib/dependabot/update_checkers/ruby/bundler/file_preparer.rb +0 -281
  33. data/lib/dependabot/update_checkers/ruby/bundler/force_updater.rb +0 -261
  34. data/lib/dependabot/update_checkers/ruby/bundler/latest_version_finder.rb +0 -169
  35. data/lib/dependabot/update_checkers/ruby/bundler/requirements_updater.rb +0 -283
  36. data/lib/dependabot/update_checkers/ruby/bundler/ruby_requirement_setter.rb +0 -115
  37. data/lib/dependabot/update_checkers/ruby/bundler/shared_bundler_helpers.rb +0 -246
  38. data/lib/dependabot/update_checkers/ruby/bundler/version_resolver.rb +0 -272
  39. data/lib/dependabot/utils/ruby/requirement.rb +0 -26
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "parser/current"
4
- require "dependabot/update_checkers/ruby/bundler"
5
-
6
- module Dependabot
7
- module UpdateCheckers
8
- module Ruby
9
- class Bundler
10
- class RubyRequirementSetter
11
- RUBY_VERSIONS =
12
- %w(1.8.7 1.9.3 2.0.0 2.1.10 2.2.10 2.3.8 2.4.5 2.5.3 2.6.0).freeze
13
-
14
- attr_reader :gemspec
15
-
16
- def initialize(gemspec:)
17
- @gemspec = gemspec
18
- end
19
-
20
- def rewrite(content)
21
- return content unless gemspec_declares_ruby_requirement?
22
-
23
- buffer = Parser::Source::Buffer.new("(gemfile_content)")
24
- buffer.source = content
25
- ast = Parser::CurrentRuby.new.parse(buffer)
26
-
27
- if declares_ruby_version?(ast)
28
- GemfileRewriter.new(
29
- ruby_version: ruby_version
30
- ).rewrite(buffer, ast)
31
- else
32
- "ruby '#{ruby_version}'\n" + content
33
- end
34
- end
35
-
36
- private
37
-
38
- def gemspec_declares_ruby_requirement?
39
- !ruby_requirement.nil?
40
- end
41
-
42
- def declares_ruby_version?(node)
43
- return false unless node.is_a?(Parser::AST::Node)
44
- return true if node.type == :send && node.children[1] == :ruby
45
-
46
- node.children.any? { |cn| declares_ruby_version?(cn) }
47
- end
48
-
49
- def ruby_version
50
- requirement = Gem::Requirement.new(ruby_requirement)
51
-
52
- ruby_version =
53
- RUBY_VERSIONS.
54
- map { |v| Gem::Version.new(v) }.sort.
55
- find { |v| requirement.satisfied_by?(v) }
56
-
57
- raise "Couldn't find Ruby version!" unless ruby_version
58
-
59
- ruby_version
60
- end
61
-
62
- # rubocop:disable Security/Eval
63
- def ruby_requirement
64
- ast = Parser::CurrentRuby.parse(gemspec.content)
65
- requirement_node = find_ruby_requirement_node(ast)
66
- return unless requirement_node
67
-
68
- eval(requirement_node.children[2].loc.expression.source)
69
- end
70
- # rubocop:enable Security/Eval
71
-
72
- def find_ruby_requirement_node(node)
73
- return unless node.is_a?(Parser::AST::Node)
74
- return node if declares_ruby_requirement?(node)
75
-
76
- node.children.find do |cn|
77
- requirement_node = find_ruby_requirement_node(cn)
78
- break requirement_node if requirement_node
79
- end
80
- end
81
-
82
- def declares_ruby_requirement?(node)
83
- return false unless node.is_a?(Parser::AST::Node)
84
-
85
- node.children[1] == :required_ruby_version=
86
- end
87
-
88
- class GemfileRewriter < Parser::TreeRewriter
89
- def initialize(ruby_version:)
90
- @ruby_version = ruby_version
91
- end
92
-
93
- def on_send(node)
94
- return unless declares_ruby_version?(node)
95
-
96
- assigned_version_node = node.children[2]
97
- replace(assigned_version_node.loc.expression, "'#{ruby_version}'")
98
- end
99
-
100
- private
101
-
102
- attr_reader :ruby_version
103
-
104
- def declares_ruby_version?(node)
105
- return false unless node.is_a?(Parser::AST::Node)
106
- return false unless node.type == :send
107
-
108
- node.children[1] == :ruby
109
- end
110
- end
111
- end
112
- end
113
- end
114
- end
115
- end
@@ -1,246 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler_definition_ruby_version_patch"
4
- require "bundler_definition_bundler_version_patch"
5
- require "bundler_git_source_patch"
6
-
7
- require "excon"
8
-
9
- require "dependabot/update_checkers/ruby/bundler"
10
- require "dependabot/shared_helpers"
11
- require "dependabot/errors"
12
-
13
- module Dependabot
14
- module UpdateCheckers
15
- module Ruby
16
- class Bundler
17
- module SharedBundlerHelpers
18
- GIT_REGEX = /reset --hard [^\s]*` in directory (?<path>[^\s]*)/.freeze
19
- GIT_REF_REGEX = /not exist in the repository (?<path>[^\s]*)\./.freeze
20
- PATH_REGEX = /The path `(?<path>.*)` does not exist/.freeze
21
- RETRYABLE_ERRORS = %w(
22
- Bundler::HTTPError
23
- Bundler::Fetcher::FallbackError
24
- ).freeze
25
- RETRYABLE_PRIVATE_REGISTRY_ERRORS = %w(
26
- Bundler::GemNotFound
27
- Gem::InvalidSpecificationException
28
- Bundler::VersionConflict
29
- Bundler::HTTPError
30
- Bundler::Fetcher::FallbackError
31
- ).freeze
32
-
33
- attr_reader :dependency_files, :credentials
34
-
35
- #########################
36
- # Bundler context setup #
37
- #########################
38
-
39
- def in_a_temporary_bundler_context(error_handling: true)
40
- base_directory = dependency_files.first.directory
41
- SharedHelpers.in_a_temporary_directory(base_directory) do |tmp_dir|
42
- write_temporary_dependency_files
43
-
44
- SharedHelpers.in_a_forked_process do
45
- # Set the path for path gemspec correctly
46
- ::Bundler.instance_variable_set(:@root, tmp_dir)
47
-
48
- # Remove installed gems from the default Rubygems index
49
- ::Gem::Specification.all = []
50
-
51
- # Set auth details
52
- relevant_credentials.each do |cred|
53
- token = cred["token"] ||
54
- "#{cred['username']}:#{cred['password']}"
55
-
56
- ::Bundler.settings.set_command_option(
57
- cred.fetch("host"),
58
- token.gsub("@", "%40F").gsub("?", "%3F")
59
- )
60
- end
61
-
62
- yield
63
- end
64
- end
65
- rescue SharedHelpers::ChildProcessFailed => error
66
- retry_count ||= 0
67
- retry_count += 1
68
- if retryable_error?(error) && retry_count <= 2
69
- sleep(rand(1.0..5.0)) && retry
70
- end
71
-
72
- raise unless error_handling
73
-
74
- # Raise more descriptive errors
75
- handle_bundler_errors(error)
76
- end
77
-
78
- def retryable_error?(error)
79
- return true if RETRYABLE_ERRORS.include?(error.error_class)
80
-
81
- unless RETRYABLE_PRIVATE_REGISTRY_ERRORS.include?(error.error_class)
82
- return false
83
- end
84
-
85
- private_registry_credentials.any?
86
- end
87
-
88
- # rubocop:disable Metrics/CyclomaticComplexity
89
- # rubocop:disable Metrics/PerceivedComplexity
90
- # rubocop:disable Metrics/AbcSize
91
- # rubocop:disable Metrics/MethodLength
92
- def handle_bundler_errors(error)
93
- msg = error.error_class + " with message: " + error.error_message
94
-
95
- case error.error_class
96
- when "Bundler::Dsl::DSLError", "Bundler::GemspecError"
97
- # We couldn't evaluate the Gemfile, let alone resolve it
98
- raise Dependabot::DependencyFileNotEvaluatable, msg
99
- when "Bundler::Source::Git::MissingGitRevisionError"
100
- gem_name =
101
- error.error_message.match(GIT_REF_REGEX).
102
- named_captures["path"].
103
- split("/").last
104
- raise GitDependencyReferenceNotFound, gem_name
105
- when "Bundler::PathError"
106
- gem_name =
107
- error.error_message.match(PATH_REGEX).
108
- named_captures["path"].
109
- split("/").last.split("-")[0..-2].join
110
- raise Dependabot::PathDependenciesNotReachable, [gem_name]
111
- when "Bundler::Source::Git::GitCommandError"
112
- if error.error_message.match?(GIT_REGEX)
113
- # We couldn't find the specified branch / commit (or the two
114
- # weren't compatible).
115
- gem_name =
116
- error.error_message.match(GIT_REGEX).
117
- named_captures["path"].
118
- split("/").last.split("-")[0..-2].join
119
- raise GitDependencyReferenceNotFound, gem_name
120
- end
121
-
122
- bad_uris = inaccessible_git_dependencies.map { |s| s.source.uri }
123
- raise unless bad_uris.any?
124
-
125
- # We don't have access to one of repos required
126
- raise Dependabot::GitDependenciesNotReachable, bad_uris
127
- when "Bundler::GemNotFound", "Gem::InvalidSpecificationException",
128
- "Bundler::VersionConflict"
129
- # Bundler threw an error during resolution. Any of:
130
- # - the gem doesn't exist in any of the specified sources
131
- # - the gem wasn't specified properly
132
- # - the gem was specified at an incompatible version
133
- raise Dependabot::DependencyFileNotResolvable, msg
134
- when "Bundler::Fetcher::AuthenticationRequiredError"
135
- regex = /bundle config (?<source>.*) username:password/
136
- source = error.error_message.match(regex)[:source]
137
- raise Dependabot::PrivateSourceAuthenticationFailure, source
138
- when "Bundler::Fetcher::BadAuthenticationError"
139
- regex = /Bad username or password for (?<source>.*)\.$/
140
- source = error.error_message.match(regex)[:source]
141
- raise Dependabot::PrivateSourceAuthenticationFailure, source
142
- when "Bundler::Fetcher::CertificateFailureError"
143
- regex = /verify the SSL certificate for (?<source>.*)\.$/
144
- source = error.error_message.match(regex)[:source]
145
- raise Dependabot::PrivateSourceCertificateFailure, source
146
- when "Bundler::HTTPError"
147
- regex = /Could not fetch specs from (?<source>.*)$/
148
- if error.error_message.match?(regex)
149
- source = error.error_message.match(regex)[:source]
150
- raise if source.include?("rubygems.org")
151
-
152
- raise Dependabot::PrivateSourceTimedOut, source
153
- end
154
-
155
- # JFrog can serve a 403 if the credentials provided are good but
156
- # don't have access to a particular gem.
157
- raise unless error.error_message.include?("permitted to deploy")
158
- raise unless jfrog_source
159
-
160
- raise Dependabot::PrivateSourceAuthenticationFailure, jfrog_source
161
- else raise
162
- end
163
- end
164
- # rubocop:enable Metrics/CyclomaticComplexity
165
- # rubocop:enable Metrics/PerceivedComplexity
166
- # rubocop:enable Metrics/AbcSize
167
- # rubocop:enable Metrics/MethodLength
168
-
169
- def inaccessible_git_dependencies
170
- in_a_temporary_bundler_context(error_handling: false) do
171
- ::Bundler::Definition.build(gemfile.name, nil, {}).dependencies.
172
- reject do |spec|
173
- next true unless spec.source.is_a?(::Bundler::Source::Git)
174
-
175
- # Piggy-back off some private Bundler methods to configure the
176
- # URI with auth details in the same way Bundler does.
177
- git_proxy = spec.source.send(:git_proxy)
178
- uri = spec.source.uri.gsub("git://", "https://")
179
- uri = git_proxy.send(:configured_uri_for, uri)
180
- uri += ".git" unless uri.end_with?(".git")
181
- uri += "/info/refs?service=git-upload-pack"
182
-
183
- begin
184
- Excon.get(
185
- uri,
186
- idempotent: true,
187
- **SharedHelpers.excon_defaults
188
- ).status == 200
189
- rescue Excon::Error::Socket, Excon::Error::Timeout
190
- false
191
- end
192
- end
193
- end
194
- end
195
-
196
- def jfrog_source
197
- in_a_temporary_bundler_context(error_handling: false) do
198
- ::Bundler::Definition.build(gemfile.name, nil, {}).
199
- send(:sources).
200
- rubygems_remotes.
201
- find { |uri| uri.host.include?("jfrog") }&.
202
- host
203
- end
204
- end
205
-
206
- def write_temporary_dependency_files
207
- dependency_files.each do |file|
208
- path = file.name
209
- FileUtils.mkdir_p(Pathname.new(path).dirname)
210
- File.write(path, file.content)
211
- end
212
-
213
- File.write(lockfile.name, sanitized_lockfile_body) if lockfile
214
- end
215
-
216
- def relevant_credentials
217
- private_registry_credentials + git_source_credentials
218
- end
219
-
220
- def private_registry_credentials
221
- credentials.select { |cred| cred["type"] == "rubygems_server" }
222
- end
223
-
224
- def git_source_credentials
225
- credentials.select { |cred| cred["type"] == "git_source" }
226
- end
227
-
228
- def gemfile
229
- dependency_files.find { |f| f.name == "Gemfile" } ||
230
- dependency_files.find { |f| f.name == "gems.rb" }
231
- end
232
-
233
- def lockfile
234
- dependency_files.find { |f| f.name == "Gemfile.lock" } ||
235
- dependency_files.find { |f| f.name == "gems.locked" }
236
- end
237
-
238
- def sanitized_lockfile_body
239
- re = FileUpdaters::Ruby::Bundler::LockfileUpdater::LOCKFILE_ENDING
240
- lockfile.content.gsub(re, "")
241
- end
242
- end
243
- end
244
- end
245
- end
246
- end
@@ -1,272 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler_definition_ruby_version_patch"
4
- require "bundler_definition_bundler_version_patch"
5
- require "bundler_git_source_patch"
6
-
7
- require "excon"
8
-
9
- require "dependabot/update_checkers/ruby/bundler"
10
- require "dependabot/file_updaters/ruby/bundler/lockfile_updater"
11
- require "dependabot/utils/ruby/requirement"
12
- require "dependabot/shared_helpers"
13
- require "dependabot/errors"
14
-
15
- module Dependabot
16
- module UpdateCheckers
17
- module Ruby
18
- class Bundler
19
- class VersionResolver
20
- require_relative "file_preparer"
21
- require_relative "latest_version_finder"
22
- require_relative "shared_bundler_helpers"
23
- include SharedBundlerHelpers
24
-
25
- GEM_NOT_FOUND_ERROR_REGEX = /locked to (?<name>[^\s]+) \(/.freeze
26
-
27
- def initialize(dependency:, unprepared_dependency_files:,
28
- credentials:, ignored_versions:,
29
- replacement_git_pin: nil, remove_git_source: false,
30
- unlock_requirement: true,
31
- latest_allowable_version: nil)
32
- @dependency = dependency
33
- @unprepared_dependency_files = unprepared_dependency_files
34
- @credentials = credentials
35
- @ignored_versions = ignored_versions
36
- @replacement_git_pin = replacement_git_pin
37
- @remove_git_source = remove_git_source
38
- @unlock_requirement = unlock_requirement
39
- @latest_allowable_version = latest_allowable_version
40
- end
41
-
42
- def latest_resolvable_version_details
43
- @latest_resolvable_version_details ||=
44
- fetch_latest_resolvable_version_details
45
- end
46
-
47
- private
48
-
49
- attr_reader :dependency, :unprepared_dependency_files, :credentials,
50
- :ignored_versions, :replacement_git_pin,
51
- :latest_allowable_version
52
-
53
- def remove_git_source?
54
- @remove_git_source
55
- end
56
-
57
- def unlock_requirement?
58
- @unlock_requirement
59
- end
60
-
61
- def dependency_files
62
- @dependency_files ||=
63
- FilePreparer.new(
64
- dependency: dependency,
65
- dependency_files: unprepared_dependency_files,
66
- replacement_git_pin: replacement_git_pin,
67
- remove_git_source: remove_git_source?,
68
- unlock_requirement: unlock_requirement?,
69
- latest_allowable_version: latest_allowable_version
70
- ).prepared_dependency_files
71
- end
72
-
73
- # rubocop:disable Metrics/CyclomaticComplexity
74
- # rubocop:disable Metrics/PerceivedComplexity
75
- def fetch_latest_resolvable_version_details
76
- return latest_version_details unless gemfile
77
-
78
- in_a_temporary_bundler_context do
79
- dep = dependency_from_definition
80
-
81
- # If the dependency wasn't found in the definition, but *is*
82
- # included in a gemspec, it's because the Gemfile didn't import
83
- # the gemspec. This is unusual, but the correct behaviour if/when
84
- # it happens is to behave as if the repo was gemspec-only.
85
- if dep.nil? && dependency.requirements.any?
86
- next latest_version_details
87
- end
88
-
89
- # Otherwise, if the dependency wasn't found it's because it is a
90
- # subdependency that was removed when attempting to update it.
91
- next nil if dep.nil?
92
-
93
- # If the old Gemfile index was used then it won't have checked
94
- # Ruby compatibility. Fix that by doing the check manually (and
95
- # saying no update is possible if the Ruby version is a mismatch)
96
- next nil if ruby_version_incompatible?(dep)
97
-
98
- details = { version: dep.version }
99
- if dep.source.instance_of?(::Bundler::Source::Git)
100
- details[:commit_sha] = dep.source.revision
101
- end
102
- details
103
- end
104
- rescue Dependabot::DependencyFileNotResolvable => error
105
- return if ignored_versions.any? && !dependency.appears_in_lockfile?
106
- raise unless ruby_lock_error?(error)
107
-
108
- @gemspec_ruby_unlocked = true
109
- regenerate_dependency_files_without_ruby_lock && retry
110
- end
111
- # rubocop:enable Metrics/CyclomaticComplexity
112
- # rubocop:enable Metrics/PerceivedComplexity
113
-
114
- def ruby_lock_error?(error)
115
- return false unless error.message.include?(" for gem \"ruby\0\"")
116
- return false if @gemspec_ruby_unlocked
117
-
118
- dependency_files.any? { |f| f.name.end_with?(".gemspec") }
119
- end
120
-
121
- def regenerate_dependency_files_without_ruby_lock
122
- @dependency_files =
123
- FilePreparer.new(
124
- dependency: dependency,
125
- dependency_files: unprepared_dependency_files,
126
- replacement_git_pin: replacement_git_pin,
127
- remove_git_source: remove_git_source?,
128
- unlock_requirement: unlock_requirement?,
129
- latest_allowable_version: latest_allowable_version,
130
- lock_ruby_version: false
131
- ).prepared_dependency_files
132
- end
133
-
134
- # rubocop:disable Metrics/CyclomaticComplexity
135
- # rubocop:disable Metrics/PerceivedComplexity
136
- def dependency_from_definition(unlock_subdependencies: true)
137
- dependencies_to_unlock = [dependency.name]
138
- dependencies_to_unlock += subdependencies if unlock_subdependencies
139
- begin
140
- definition = build_definition(dependencies_to_unlock)
141
- definition.resolve_remotely!
142
- rescue ::Bundler::GemNotFound => error
143
- unlock_yanked_gem(dependencies_to_unlock, error) && retry
144
- rescue ::Bundler::HTTPError => error
145
- # Retry network errors
146
- attempt ||= 1
147
- attempt += 1
148
- raise if attempt > 3 || !error.message.include?("Network error")
149
-
150
- retry
151
- end
152
-
153
- dep = definition.resolve.find { |d| d.name == dependency.name }
154
- return dep if dep
155
- return if dependency.requirements.any? || !unlock_subdependencies
156
-
157
- # If no definition was found and we're updating a sub-dependency,
158
- # try again but without unlocking any other sub-dependencies
159
- dependency_from_definition(unlock_subdependencies: false)
160
- end
161
- # rubocop:enable Metrics/CyclomaticComplexity
162
- # rubocop:enable Metrics/PerceivedComplexity
163
-
164
- def unlock_yanked_gem(dependencies_to_unlock, error)
165
- raise unless error.message.match?(GEM_NOT_FOUND_ERROR_REGEX)
166
-
167
- gem_name = error.message.match(GEM_NOT_FOUND_ERROR_REGEX).
168
- named_captures["name"]
169
- raise if dependencies_to_unlock.include?(gem_name)
170
-
171
- dependencies_to_unlock << gem_name
172
- end
173
-
174
- def subdependencies
175
- # If there's no lockfile we don't need to worry about
176
- # subdependencies
177
- return [] unless lockfile
178
-
179
- all_deps = ::Bundler::LockfileParser.new(sanitized_lockfile_body).
180
- specs.map(&:name).map(&:to_s)
181
- top_level = build_definition([]).dependencies.
182
- map(&:name).map(&:to_s)
183
-
184
- all_deps - top_level
185
- end
186
-
187
- def ruby_version_incompatible?(dep)
188
- return false unless dep.source.is_a?(::Bundler::Source::Rubygems)
189
-
190
- fetcher = dep.source.fetchers.first.fetchers.first
191
-
192
- # It's only the old index we have a problem with
193
- return false unless fetcher.is_a?(::Bundler::Fetcher::Dependency)
194
-
195
- # If no Ruby version is specified, we don't have a problem
196
- return false unless ruby_version
197
-
198
- versions = Excon.get(
199
- "#{fetcher.fetch_uri}api/v1/versions/#{dependency.name}.json",
200
- idempotent: true,
201
- **SharedHelpers.excon_defaults
202
- )
203
-
204
- # Give the benefit of the doubt if something goes wrong fetching
205
- # version details (could be that it's a private index, etc.)
206
- return false unless versions.status == 200
207
-
208
- ruby_requirement =
209
- JSON.parse(versions.body).
210
- find { |details| details["number"] == dep.version.to_s }&.
211
- fetch("ruby_version", nil)
212
-
213
- # Give the benefit of the doubt if we can't find the version's
214
- # required Ruby version.
215
- return false unless ruby_requirement
216
-
217
- ruby_requirement = Utils::Ruby::Requirement.new(ruby_requirement)
218
-
219
- !ruby_requirement.satisfied_by?(ruby_version)
220
- rescue JSON::ParserError, Excon::Error::Socket, Excon::Error::Timeout
221
- # Give the benefit of the doubt if something goes wrong fetching
222
- # version details (could be that it's a private index, etc.)
223
- false
224
- end
225
-
226
- def build_definition(dependencies_to_unlock)
227
- # Note: we lock shared dependencies to avoid any top-level
228
- # dependencies getting unlocked (which would happen if they were
229
- # also subdependencies of the dependency being unlocked)
230
- ::Bundler::Definition.build(
231
- gemfile.name,
232
- lockfile&.name,
233
- gems: dependencies_to_unlock,
234
- lock_shared_dependencies: true
235
- )
236
- end
237
-
238
- def ruby_version
239
- return nil unless gemfile
240
-
241
- @ruby_version ||= build_definition([]).ruby_version&.gem_version
242
- end
243
-
244
- def latest_version_details
245
- @latest_version_details ||=
246
- LatestVersionFinder.new(
247
- dependency: dependency,
248
- dependency_files: dependency_files,
249
- credentials: credentials,
250
- ignored_versions: ignored_versions
251
- ).latest_version_details
252
- end
253
-
254
- def gemfile
255
- dependency_files.find { |f| f.name == "Gemfile" } ||
256
- dependency_files.find { |f| f.name == "gems.rb" }
257
- end
258
-
259
- def lockfile
260
- dependency_files.find { |f| f.name == "Gemfile.lock" } ||
261
- dependency_files.find { |f| f.name == "gems.locked" }
262
- end
263
-
264
- def sanitized_lockfile_body
265
- re = FileUpdaters::Ruby::Bundler::LockfileUpdater::LOCKFILE_ENDING
266
- lockfile.content.gsub(re, "")
267
- end
268
- end
269
- end
270
- end
271
- end
272
- end