dependabot-bundler 0.95.5 → 0.95.6

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