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,169 +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/utils/ruby/requirement"
11
- require "dependabot/shared_helpers"
12
- require "dependabot/errors"
13
-
14
- module Dependabot
15
- module UpdateCheckers
16
- module Ruby
17
- class Bundler
18
- class LatestVersionFinder
19
- require_relative "shared_bundler_helpers"
20
- include SharedBundlerHelpers
21
-
22
- def initialize(dependency:, dependency_files:, credentials:,
23
- ignored_versions:)
24
- @dependency = dependency
25
- @dependency_files = dependency_files
26
- @credentials = credentials
27
- @ignored_versions = ignored_versions
28
- end
29
-
30
- def latest_version_details
31
- @latest_version_details ||= fetch_latest_version_details
32
- end
33
-
34
- private
35
-
36
- attr_reader :dependency, :dependency_files, :credentials,
37
- :ignored_versions
38
-
39
- def fetch_latest_version_details
40
- if dependency.name == "bundler"
41
- return latest_rubygems_version_details
42
- end
43
-
44
- case dependency_source
45
- when NilClass then latest_rubygems_version_details
46
- when ::Bundler::Source::Rubygems
47
- if dependency_source.remotes.none? ||
48
- dependency_source.remotes.first.to_s == "https://rubygems.org/"
49
- latest_rubygems_version_details
50
- else
51
- latest_private_version_details
52
- end
53
- when ::Bundler::Source::Git then latest_git_version_details
54
- end
55
- end
56
-
57
- def latest_rubygems_version_details
58
- response = Excon.get(
59
- "https://rubygems.org/api/v1/versions/#{dependency.name}.json",
60
- idempotent: true,
61
- **SharedHelpers.excon_defaults
62
- )
63
-
64
- relevant_versions =
65
- JSON.parse(response.body).
66
- reject do |d|
67
- version = Gem::Version.new(d["number"])
68
- next true if version.prerelease? && !wants_prerelease?
69
- next true if ignore_reqs.any? { |r| r.satisfied_by?(version) }
70
-
71
- false
72
- end
73
-
74
- dep = relevant_versions.max_by { |d| Gem::Version.new(d["number"]) }
75
- return unless dep
76
-
77
- {
78
- version: Gem::Version.new(dep["number"]),
79
- sha: dep["sha"]
80
- }
81
- rescue JSON::ParserError, Excon::Error::Timeout
82
- nil
83
- end
84
-
85
- def latest_private_version_details
86
- in_a_temporary_bundler_context do
87
- spec =
88
- dependency_source.
89
- fetchers.flat_map do |fetcher|
90
- fetcher.
91
- specs_with_retry([dependency.name], dependency_source).
92
- search_all(dependency.name).
93
- reject { |s| s.version.prerelease? && !wants_prerelease? }.
94
- reject do |s|
95
- ignore_reqs.any? { |r| r.satisfied_by?(s.version) }
96
- end
97
- end.
98
- max_by(&:version)
99
- spec.nil? ? nil : { version: spec.version }
100
- end
101
- end
102
-
103
- def latest_git_version_details
104
- dependency_source_details =
105
- dependency.requirements.map { |r| r.fetch(:source) }.
106
- uniq.compact.first
107
-
108
- in_a_temporary_bundler_context do
109
- SharedHelpers.with_git_configured(credentials: credentials) do
110
- # Note: we don't set `ref`, as we want to unpin the dependency
111
- source = ::Bundler::Source::Git.new(
112
- "uri" => dependency_source_details[:url],
113
- "branch" => dependency_source_details[:branch],
114
- "name" => dependency.name,
115
- "submodules" => true
116
- )
117
-
118
- # Tell Bundler we're fine with fetching the source remotely
119
- source.instance_variable_set(:@allow_remote, true)
120
-
121
- spec = source.specs.first
122
- { version: spec.version, commit_sha: spec.source.revision }
123
- end
124
- end
125
- end
126
-
127
- def wants_prerelease?
128
- @wants_prerelease ||=
129
- begin
130
- current_version = dependency.version
131
- if current_version && Gem::Version.correct?(current_version) &&
132
- Gem::Version.new(current_version).prerelease?
133
- return true
134
- end
135
-
136
- dependency.requirements.any? do |req|
137
- req[:requirement].match?(/[a-z]/i)
138
- end
139
- end
140
- end
141
-
142
- def dependency_source
143
- return nil unless gemfile
144
-
145
- @dependency_source ||=
146
- in_a_temporary_bundler_context do
147
- definition = ::Bundler::Definition.build(gemfile.name, nil, {})
148
-
149
- specified_source =
150
- definition.dependencies.
151
- find { |dep| dep.name == dependency.name }&.source
152
-
153
- specified_source || definition.send(:sources).default_source
154
- end
155
- end
156
-
157
- def ignore_reqs
158
- ignored_versions.map { |req| Gem::Requirement.new(req.split(",")) }
159
- end
160
-
161
- def gemfile
162
- dependency_files.find { |f| f.name == "Gemfile" } ||
163
- dependency_files.find { |f| f.name == "gems.rb" }
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end
@@ -1,283 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/update_checkers/ruby/bundler"
4
-
5
- module Dependabot
6
- module UpdateCheckers
7
- module Ruby
8
- class Bundler
9
- class RequirementsUpdater
10
- class UnfixableRequirement < StandardError; end
11
-
12
- ALLOWED_UPDATE_STRATEGIES =
13
- %i(bump_versions bump_versions_if_necessary).freeze
14
-
15
- def initialize(requirements:, update_strategy:, updated_source:,
16
- latest_version:, latest_resolvable_version:)
17
- @requirements = requirements
18
- @latest_version = Gem::Version.new(latest_version) if latest_version
19
- @updated_source = updated_source
20
- @update_strategy = update_strategy
21
-
22
- check_update_strategy
23
-
24
- return unless latest_resolvable_version
25
-
26
- @latest_resolvable_version =
27
- Gem::Version.new(latest_resolvable_version)
28
- end
29
-
30
- def updated_requirements
31
- requirements.map do |req|
32
- if req[:file].match?(/\.gemspec/)
33
- update_gemspec_requirement(req)
34
- else
35
- # If a requirement doesn't come from a gemspec, it must be from
36
- # a Gemfile.
37
- update_gemfile_requirement(req)
38
- end
39
- end
40
- end
41
-
42
- private
43
-
44
- attr_reader :requirements, :updated_source,
45
- :latest_version, :latest_resolvable_version,
46
- :update_strategy
47
-
48
- def check_update_strategy
49
- return if ALLOWED_UPDATE_STRATEGIES.include?(update_strategy)
50
-
51
- raise "Unknown update strategy: #{update_strategy}"
52
- end
53
-
54
- def update_gemfile_requirement(req)
55
- req = req.merge(source: updated_source)
56
- return req unless latest_resolvable_version
57
-
58
- case update_strategy
59
- when :bump_versions
60
- update_version_requirement(req)
61
- when :bump_versions_if_necessary
62
- update_version_requirement_if_needed(req)
63
- else raise "Unexpected update strategy: #{update_strategy}"
64
- end
65
- end
66
-
67
- def update_version_requirement_if_needed(req)
68
- return req if new_version_satisfies?(req)
69
-
70
- update_version_requirement(req)
71
- end
72
-
73
- def update_version_requirement(req)
74
- requirements =
75
- req[:requirement].split(",").map { |r| Gem::Requirement.new(r) }
76
-
77
- new_requirement =
78
- if requirements.any?(&:exact?) then latest_resolvable_version.to_s
79
- elsif requirements.any? { |r| r.to_s.start_with?("~>") }
80
- tw_req = requirements.find { |r| r.to_s.start_with?("~>") }
81
- update_twiddle_version(tw_req, latest_resolvable_version).to_s
82
- else
83
- update_gemfile_range(requirements).map(&:to_s).join(", ")
84
- end
85
-
86
- req.merge(requirement: new_requirement)
87
- end
88
-
89
- def new_version_satisfies?(req)
90
- original_req = Gem::Requirement.new(req[:requirement].split(","))
91
- original_req.satisfied_by?(latest_resolvable_version)
92
- end
93
-
94
- def update_gemfile_range(requirements)
95
- updated_requirements =
96
- requirements.flat_map do |r|
97
- next r if r.satisfied_by?(latest_resolvable_version)
98
-
99
- case op = r.requirements.first.first
100
- when "<", "<="
101
- [update_greatest_version(r, latest_resolvable_version)]
102
- when "!="
103
- []
104
- else
105
- raise "Unexpected operation for unsatisfied Gemfile "\
106
- "requirement: #{op}"
107
- end
108
- end
109
-
110
- binding_requirements(updated_requirements)
111
- end
112
-
113
- def at_same_precision(new_version, old_version)
114
- release_precision =
115
- old_version.to_s.split(".").select { |i| i.match?(/^\d+$/) }.count
116
- prerelease_precision =
117
- old_version.to_s.split(".").count - release_precision
118
-
119
- new_release =
120
- new_version.to_s.split(".").first(release_precision)
121
- new_prerelease =
122
- new_version.to_s.split(".").
123
- drop_while { |i| i.match?(/^\d+$/) }.
124
- first([prerelease_precision, 1].max)
125
-
126
- [*new_release, *new_prerelease].join(".")
127
- end
128
-
129
- # rubocop:disable Metrics/PerceivedComplexity
130
- def update_gemspec_requirement(req)
131
- return req unless latest_version && latest_resolvable_version
132
-
133
- requirements =
134
- req[:requirement].split(",").map { |r| Gem::Requirement.new(r) }
135
-
136
- return req if requirements.all? do |r|
137
- requirement_satisfied?(r, req[:groups])
138
- end
139
-
140
- updated_requirements =
141
- requirements.flat_map do |r|
142
- next r if requirement_satisfied?(r, req[:groups])
143
-
144
- if req[:groups] == ["development"] then bumped_requirements(r)
145
- else widened_requirements(r)
146
- end
147
- end
148
-
149
- updated_requirements = binding_requirements(updated_requirements)
150
- req.merge(requirement: updated_requirements.map(&:to_s).join(", "))
151
- rescue UnfixableRequirement
152
- req.merge(requirement: :unfixable)
153
- end
154
- # rubocop:enable Metrics/PerceivedComplexity
155
-
156
- def requirement_satisfied?(req, groups)
157
- if groups == ["development"]
158
- req.satisfied_by?(latest_resolvable_version)
159
- else
160
- req.satisfied_by?(latest_version)
161
- end
162
- end
163
-
164
- def binding_requirements(requirements)
165
- grouped_by_operator =
166
- requirements.group_by { |r| r.requirements.first.first }
167
-
168
- binding_reqs = grouped_by_operator.flat_map do |operator, reqs|
169
- case operator
170
- when "<", "<=" then reqs.min_by { |r| r.requirements.first.last }
171
- when ">", ">=" then reqs.max_by { |r| r.requirements.first.last }
172
- else requirements
173
- end
174
- end.uniq
175
-
176
- binding_reqs << Gem::Requirement.new if binding_reqs.empty?
177
- binding_reqs.sort_by { |r| r.requirements.first.last }
178
- end
179
-
180
- def widened_requirements(req)
181
- op, version = req.requirements.first
182
-
183
- case op
184
- when "=", nil
185
- if version < latest_resolvable_version
186
- [Gem::Requirement.new("#{op} #{latest_resolvable_version}")]
187
- else
188
- req
189
- end
190
- when "<", "<=" then [update_greatest_version(req, latest_version)]
191
- when "~>" then convert_twidle_to_range(req, latest_version)
192
- when "!=" then []
193
- when ">", ">=" then raise UnfixableRequirement
194
- else raise "Unexpected operation for requirement: #{op}"
195
- end
196
- end
197
-
198
- def bumped_requirements(req)
199
- op, version = req.requirements.first
200
-
201
- case op
202
- when "=", nil
203
- if version < latest_resolvable_version
204
- [Gem::Requirement.new("#{op} #{latest_resolvable_version}")]
205
- else
206
- req
207
- end
208
- when "~>"
209
- [update_twiddle_version(req, latest_resolvable_version)]
210
- when "<", "<=" then [update_greatest_version(req, latest_version)]
211
- when "!=" then []
212
- when ">", ">=" then raise UnfixableRequirement
213
- else raise "Unexpected operation for requirement: #{op}"
214
- end
215
- end
216
-
217
- # rubocop:disable Metrics/AbcSize
218
- def convert_twidle_to_range(requirement, version_to_be_permitted)
219
- version = requirement.requirements.first.last
220
- version = version.release if version.prerelease?
221
-
222
- index_to_update = [version.segments.count - 2, 0].max
223
-
224
- ub_segments = version_to_be_permitted.segments
225
- ub_segments << 0 while ub_segments.count <= index_to_update
226
- ub_segments = ub_segments[0..index_to_update]
227
- ub_segments[index_to_update] += 1
228
-
229
- lb_segments = version.segments
230
- lb_segments.pop while lb_segments.any? && lb_segments.last.zero?
231
-
232
- if lb_segments.none?
233
- return [Gem::Requirement.new("< #{ub_segments.join('.')}")]
234
- end
235
-
236
- # Ensure versions have the same length as each other (cosmetic)
237
- length = [lb_segments.count, ub_segments.count].max
238
- lb_segments.fill(0, lb_segments.count...length)
239
- ub_segments.fill(0, ub_segments.count...length)
240
-
241
- [
242
- Gem::Requirement.new(">= #{lb_segments.join('.')}"),
243
- Gem::Requirement.new("< #{ub_segments.join('.')}")
244
- ]
245
- end
246
- # rubocop:enable Metrics/AbcSize
247
-
248
- # Updates the version in a "~>" constraint to allow the given version
249
- def update_twiddle_version(requirement, version_to_be_permitted)
250
- old_version = requirement.requirements.first.last
251
- updated_v = at_same_precision(version_to_be_permitted, old_version)
252
- Gem::Requirement.new("~> #{updated_v}")
253
- end
254
-
255
- # Updates the version in a "<" or "<=" constraint to allow the given
256
- # version
257
- def update_greatest_version(requirement, version_to_be_permitted)
258
- if version_to_be_permitted.is_a?(String)
259
- version_to_be_permitted =
260
- Gem::Version.new(version_to_be_permitted)
261
- end
262
- op, version = requirement.requirements.first
263
- version = version.release if version.prerelease?
264
-
265
- index_to_update =
266
- version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
267
-
268
- new_segments = version.segments.map.with_index do |_, index|
269
- if index < index_to_update
270
- version_to_be_permitted.segments[index]
271
- elsif index == index_to_update
272
- version_to_be_permitted.segments[index] + 1
273
- else 0
274
- end
275
- end
276
-
277
- Gem::Requirement.new("#{op} #{new_segments.join('.')}")
278
- end
279
- end
280
- end
281
- end
282
- end
283
- end