dependabot-bundler 0.333.0 → 0.335.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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/v2/lib/functions/force_updater.rb +7 -2
  3. data/helpers/v2/lib/functions/version_resolver.rb +6 -2
  4. data/helpers/v2/spec/functions/conflicting_dependency_resolver_spec.rb +64 -52
  5. data/helpers/v2/spec/functions/dependency_source_spec.rb +14 -10
  6. data/helpers/v2/spec/functions/version_resolver_spec.rb +4 -2
  7. data/lib/dependabot/bundler/file_fetcher.rb +12 -6
  8. data/lib/dependabot/bundler/file_parser.rb +4 -2
  9. data/lib/dependabot/bundler/file_updater/gemspec_updater.rb +13 -6
  10. data/lib/dependabot/bundler/file_updater/git_pin_replacer.rb +27 -6
  11. data/lib/dependabot/bundler/file_updater/git_source_remover.rb +14 -2
  12. data/lib/dependabot/bundler/file_updater/lockfile_updater.rb +90 -26
  13. data/lib/dependabot/bundler/file_updater/requirement_replacer.rb +92 -17
  14. data/lib/dependabot/bundler/file_updater.rb +48 -19
  15. data/lib/dependabot/bundler/metadata_finder.rb +61 -30
  16. data/lib/dependabot/bundler/package/package_details_fetcher.rb +60 -2
  17. data/lib/dependabot/bundler/requirement.rb +3 -2
  18. data/lib/dependabot/bundler/update_checker/file_preparer.rb +81 -25
  19. data/lib/dependabot/bundler/update_checker/force_updater.rb +11 -5
  20. data/lib/dependabot/bundler/update_checker/latest_version_finder/dependency_source.rb +53 -15
  21. data/lib/dependabot/bundler/update_checker/latest_version_finder.rb +4 -2
  22. data/lib/dependabot/bundler/update_checker/requirements_updater.rb +92 -31
  23. data/lib/dependabot/bundler/update_checker/version_resolver.rb +14 -7
  24. data/lib/dependabot/bundler/update_checker.rb +14 -7
  25. metadata +12 -12
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -23,21 +23,41 @@ module Dependabot
23
23
  T::Array[Dependabot::RequirementsUpdateStrategy]
24
24
  )
25
25
 
26
- def initialize(requirements:, update_strategy:, updated_source:,
27
- latest_version:, latest_resolvable_version:)
26
+ sig do
27
+ params(
28
+ requirements: T::Array[T::Hash[Symbol, T.untyped]],
29
+ update_strategy: Dependabot::RequirementsUpdateStrategy,
30
+ updated_source: T.nilable(T::Hash[Symbol, T.untyped]),
31
+ latest_version: T.nilable(String),
32
+ latest_resolvable_version: T.nilable(String)
33
+ ).void
34
+ end
35
+ def initialize(
36
+ requirements:,
37
+ update_strategy:,
38
+ updated_source:,
39
+ latest_version:,
40
+ latest_resolvable_version:
41
+ )
28
42
  @requirements = requirements
29
- @latest_version = Dependabot::Bundler::Version.new(latest_version) if latest_version
43
+ @latest_version = T.let(
44
+ (T.cast(Dependabot::Bundler::Version.new(latest_version), Dependabot::Bundler::Version) if latest_version),
45
+ T.nilable(Dependabot::Bundler::Version)
46
+ )
30
47
  @updated_source = updated_source
31
48
  @update_strategy = update_strategy
32
49
 
33
50
  check_update_strategy
34
51
 
35
- return unless latest_resolvable_version
36
-
37
- @latest_resolvable_version =
38
- Dependabot::Bundler::Version.new(latest_resolvable_version)
52
+ @latest_resolvable_version = T.let(
53
+ if latest_resolvable_version
54
+ T.cast(Dependabot::Bundler::Version.new(latest_resolvable_version), Dependabot::Bundler::Version)
55
+ end,
56
+ T.nilable(Dependabot::Bundler::Version)
57
+ )
39
58
  end
40
59
 
60
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
41
61
  def updated_requirements
42
62
  return requirements if update_strategy.lockfile_only?
43
63
 
@@ -54,18 +74,29 @@ module Dependabot
54
74
 
55
75
  private
56
76
 
77
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
57
78
  attr_reader :requirements
79
+
80
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
58
81
  attr_reader :updated_source
82
+
83
+ sig { returns(T.nilable(Dependabot::Bundler::Version)) }
59
84
  attr_reader :latest_version
85
+
86
+ sig { returns(T.nilable(Dependabot::Bundler::Version)) }
60
87
  attr_reader :latest_resolvable_version
88
+
89
+ sig { returns(Dependabot::RequirementsUpdateStrategy) }
61
90
  attr_reader :update_strategy
62
91
 
92
+ sig { void }
63
93
  def check_update_strategy
64
94
  return if ALLOWED_UPDATE_STRATEGIES.include?(update_strategy)
65
95
 
66
96
  raise "Unknown update strategy: #{update_strategy}"
67
97
  end
68
98
 
99
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
69
100
  def update_gemfile_requirement(req)
70
101
  req = req.merge(source: updated_source)
71
102
  return req unless latest_resolvable_version
@@ -79,12 +110,14 @@ module Dependabot
79
110
  end
80
111
  end
81
112
 
113
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
82
114
  def update_version_requirement_if_needed(req)
83
115
  return req if new_version_satisfies?(req)
84
116
 
85
117
  update_version_requirement(req)
86
118
  end
87
119
 
120
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
88
121
  def update_version_requirement(req)
89
122
  requirements =
90
123
  req[:requirement].split(",").map { |r| Gem::Requirement.new(r) }
@@ -93,7 +126,7 @@ module Dependabot
93
126
  if requirements.any?(&:exact?) then latest_resolvable_version.to_s
94
127
  elsif requirements.any? { |r| r.to_s.start_with?("~>") }
95
128
  tw_req = requirements.find { |r| r.to_s.start_with?("~>") }
96
- update_twiddle_version(tw_req, latest_resolvable_version).to_s
129
+ update_twiddle_version(tw_req, T.must(latest_resolvable_version)).to_s
97
130
  else
98
131
  update_gemfile_range(requirements).map(&:to_s).join(", ")
99
132
  end
@@ -101,10 +134,14 @@ module Dependabot
101
134
  req.merge(requirement: new_requirement)
102
135
  end
103
136
 
137
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
104
138
  def new_version_satisfies?(req)
105
- Requirement.satisfied_by?(req, latest_resolvable_version)
139
+ return false unless latest_resolvable_version
140
+
141
+ Requirement.satisfied_by?(req, T.must(latest_resolvable_version))
106
142
  end
107
143
 
144
+ sig { params(requirements: T::Array[Gem::Requirement]).returns(T::Array[Gem::Requirement]) }
108
145
  def update_gemfile_range(requirements)
109
146
  updated_requirements =
110
147
  requirements.flat_map do |r|
@@ -112,7 +149,7 @@ module Dependabot
112
149
 
113
150
  case op = r.requirements.first.first
114
151
  when "<", "<="
115
- [update_greatest_version(r, latest_resolvable_version)]
152
+ [update_greatest_version(r, T.must(latest_resolvable_version))]
116
153
  when "!="
117
154
  []
118
155
  else
@@ -124,6 +161,7 @@ module Dependabot
124
161
  binding_requirements(updated_requirements)
125
162
  end
126
163
 
164
+ sig { params(new_version: Dependabot::Bundler::Version, old_version: Gem::Version).returns(String) }
127
165
  def at_same_precision(new_version, old_version)
128
166
  release_precision = old_version.to_s.split(".")
129
167
  .take_while { |i| i.match?(/^\d+$/) }.count
@@ -141,6 +179,7 @@ module Dependabot
141
179
  end
142
180
 
143
181
  # rubocop:disable Metrics/PerceivedComplexity
182
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
144
183
  def update_gemspec_requirement(req)
145
184
  req = req.merge(source: updated_source) if req.fetch(:source)
146
185
  return req unless latest_version && latest_resolvable_version
@@ -169,14 +208,16 @@ module Dependabot
169
208
  end
170
209
  # rubocop:enable Metrics/PerceivedComplexity
171
210
 
211
+ sig { params(req: Gem::Requirement, groups: T::Array[String]).returns(T::Boolean) }
172
212
  def requirement_satisfied?(req, groups)
173
213
  if groups == ["development"]
174
- req.satisfied_by?(latest_resolvable_version)
214
+ req.satisfied_by?(T.must(latest_resolvable_version))
175
215
  else
176
- req.satisfied_by?(latest_version)
216
+ req.satisfied_by?(T.must(latest_version))
177
217
  end
178
218
  end
179
219
 
220
+ sig { params(requirements: T::Array[Gem::Requirement]).returns(T::Array[Gem::Requirement]) }
180
221
  def binding_requirements(requirements)
181
222
  grouped_by_operator =
182
223
  requirements.group_by { |r| r.requirements.first.first }
@@ -187,12 +228,13 @@ module Dependabot
187
228
  when ">", ">=" then reqs.max_by { |r| r.requirements.first.last }
188
229
  else requirements
189
230
  end
190
- end.uniq
231
+ end.compact.uniq
191
232
 
192
233
  binding_reqs << Gem::Requirement.new if binding_reqs.empty?
193
234
  binding_reqs.sort_by { |r| r.requirements.first.last }
194
235
  end
195
236
 
237
+ sig { params(req: Gem::Requirement).returns(T.any(T::Array[Gem::Requirement], Gem::Requirement)) }
196
238
  def widened_requirements(req)
197
239
  op, version = req.requirements.first
198
240
 
@@ -203,61 +245,77 @@ module Dependabot
203
245
  else
204
246
  req
205
247
  end
206
- when "<", "<=" then [update_greatest_version(req, latest_version)]
207
- when "~>" then convert_twiddle_to_range(req, latest_version)
248
+ when "<", "<=" then [update_greatest_version(req, T.must(latest_version))]
249
+ when "~>" then convert_twiddle_to_range(req, T.must(latest_version))
208
250
  when "!=" then []
209
251
  when ">", ">=" then raise UnfixableRequirement
210
252
  else raise "Unexpected operation for requirement: #{op}"
211
253
  end
212
254
  end
213
255
 
256
+ sig { params(req: Gem::Requirement).returns(T.any(T::Array[Gem::Requirement], Gem::Requirement)) }
214
257
  def bumped_requirements(req)
215
258
  op, version = req.requirements.first
216
259
 
217
260
  case op
218
261
  when "=", nil
219
- if version < latest_resolvable_version
262
+ if version < T.must(latest_resolvable_version)
220
263
  [Gem::Requirement.new("#{op} #{latest_resolvable_version}")]
221
264
  else
222
265
  req
223
266
  end
224
267
  when "~>"
225
- [update_twiddle_version(req, latest_resolvable_version)]
226
- when "<", "<=" then [update_greatest_version(req, latest_version)]
268
+ [update_twiddle_version(req, T.must(latest_resolvable_version))]
269
+ when "<", "<=" then [update_greatest_version(req, T.must(latest_version))]
227
270
  when "!=" then []
228
271
  when ">", ">=" then raise UnfixableRequirement
229
272
  else raise "Unexpected operation for requirement: #{op}"
230
273
  end
231
274
  end
232
275
 
276
+ # rubocop:disable Metrics/AbcSize
277
+ sig do
278
+ params(
279
+ requirement: Gem::Requirement,
280
+ version_to_be_permitted: Dependabot::Bundler::Version
281
+ )
282
+ .returns(T::Array[Gem::Requirement])
283
+ end
233
284
  def convert_twiddle_to_range(requirement, version_to_be_permitted)
234
285
  version = requirement.requirements.first.last
235
286
  version = version.release if version.prerelease?
236
287
 
237
288
  index_to_update = [version.segments.count - 2, 0].max
238
289
 
239
- ub_segments = version_to_be_permitted.segments
240
- ub_segments << 0 while ub_segments.count <= index_to_update
241
- ub_segments = ub_segments[0..index_to_update]
242
- ub_segments[index_to_update] += 1
290
+ ub_segments = version_to_be_permitted.segments.map(&:to_s)
291
+ ub_segments << "0" while ub_segments.count <= index_to_update
292
+ ub_segments = T.must(ub_segments[0..index_to_update])
293
+ ub_segments[index_to_update] = (ub_segments[index_to_update].to_i + 1).to_s
243
294
 
244
- lb_segments = version.segments
245
- lb_segments.pop while lb_segments.any? && lb_segments.last.zero?
295
+ lb_segments = version.segments.map(&:to_s)
296
+ lb_segments.pop while lb_segments.any? && lb_segments.last == "0"
246
297
 
247
298
  return [Gem::Requirement.new("< #{ub_segments.join('.')}")] if lb_segments.none?
248
299
 
249
300
  # Ensure versions have the same length as each other (cosmetic)
250
301
  length = [lb_segments.count, ub_segments.count].max
251
- lb_segments.fill(0, lb_segments.count...length)
252
- ub_segments.fill(0, ub_segments.count...length)
302
+ lb_segments.fill("0", lb_segments.count...length)
303
+ ub_segments.fill("0", ub_segments.count...length)
253
304
 
254
305
  [
255
306
  Gem::Requirement.new(">= #{lb_segments.join('.')}"),
256
307
  Gem::Requirement.new("< #{ub_segments.join('.')}")
257
308
  ]
258
309
  end
310
+ # rubocop:enable Metrics/AbcSize
259
311
 
260
312
  # Updates the version in a "~>" constraint to allow the given version
313
+ sig do
314
+ params(
315
+ requirement: Gem::Requirement,
316
+ version_to_be_permitted: Dependabot::Bundler::Version
317
+ ).returns(Gem::Requirement)
318
+ end
261
319
  def update_twiddle_version(requirement, version_to_be_permitted)
262
320
  old_version = requirement.requirements.first.last
263
321
  updated_v = at_same_precision(version_to_be_permitted, old_version)
@@ -266,10 +324,13 @@ module Dependabot
266
324
 
267
325
  # Updates the version in a "<" or "<=" constraint to allow the given
268
326
  # version
327
+ sig do
328
+ params(
329
+ requirement: Gem::Requirement,
330
+ version_to_be_permitted: Dependabot::Bundler::Version
331
+ ).returns(Gem::Requirement)
332
+ end
269
333
  def update_greatest_version(requirement, version_to_be_permitted)
270
- if version_to_be_permitted.is_a?(String)
271
- version_to_be_permitted = Dependabot::Bundler::Version.new(version_to_be_permitted)
272
- end
273
334
  op, version = requirement.requirements.first
274
335
  version = version.release if version.prerelease?
275
336
 
@@ -282,7 +343,7 @@ module Dependabot
282
343
  if index < index_to_update
283
344
  version_to_be_permitted.segments[index]
284
345
  elsif index == index_to_update
285
- version_to_be_permitted.segments[index] + 1
346
+ (version_to_be_permitted.segments[index].to_i + 1)
286
347
  elsif index > version_to_be_permitted.segments.count - 1
287
348
  nil
288
349
  else
@@ -39,13 +39,20 @@ module Dependabot
39
39
  cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
40
40
  ).void
41
41
  end
42
- def initialize(dependency:, unprepared_dependency_files:, credentials:, ignored_versions:, options:,
43
- repo_contents_path: nil,
44
- raise_on_ignored: false,
45
- replacement_git_pin: nil, remove_git_source: false,
46
- unlock_requirement: true,
47
- latest_allowable_version: nil,
48
- cooldown_options: nil)
42
+ def initialize(
43
+ dependency:,
44
+ unprepared_dependency_files:,
45
+ credentials:,
46
+ ignored_versions:,
47
+ options:,
48
+ repo_contents_path: nil,
49
+ raise_on_ignored: false,
50
+ replacement_git_pin: nil,
51
+ remove_git_source: false,
52
+ unlock_requirement: true,
53
+ latest_allowable_version: nil,
54
+ cooldown_options: nil
55
+ )
49
56
  @dependency = dependency
50
57
  @unprepared_dependency_files = unprepared_dependency_files
51
58
  @credentials = credentials
@@ -82,7 +82,7 @@ module Dependabot
82
82
 
83
83
  RequirementsUpdater.new(
84
84
  requirements: dependency.requirements,
85
- update_strategy: requirements_update_strategy,
85
+ update_strategy: T.must(requirements_update_strategy),
86
86
  updated_source: updated_source,
87
87
  latest_version: latest_version_for_req_updater,
88
88
  latest_resolvable_version: latest_resolvable_version_for_req_updater
@@ -354,8 +354,10 @@ module Dependabot
354
354
  sig { returns(Dependabot::Bundler::UpdateChecker::ForceUpdater) }
355
355
  def force_updater
356
356
  if @force_updater.nil?
357
- @force_updater = T.let(@force_updater,
358
- T.nilable(Dependabot::Bundler::UpdateChecker::ForceUpdater))
357
+ @force_updater = T.let(
358
+ @force_updater,
359
+ T.nilable(Dependabot::Bundler::UpdateChecker::ForceUpdater)
360
+ )
359
361
  end
360
362
  @force_updater ||=
361
363
  ForceUpdater.new(
@@ -372,8 +374,10 @@ module Dependabot
372
374
  sig { returns(Dependabot::GitCommitChecker) }
373
375
  def git_commit_checker
374
376
  if @git_commit_checker.nil?
375
- @git_commit_checker = T.let(@git_commit_checker,
376
- T.nilable(Dependabot::GitCommitChecker))
377
+ @git_commit_checker = T.let(
378
+ @git_commit_checker,
379
+ T.nilable(Dependabot::GitCommitChecker)
380
+ )
377
381
  end
378
382
  @git_commit_checker ||=
379
383
  GitCommitChecker.new(
@@ -432,8 +436,11 @@ module Dependabot
432
436
  latest_allowable_version: T.nilable(T.any(String, Dependabot::Bundler::Version))
433
437
  ).returns(T::Array[Dependabot::DependencyFile])
434
438
  end
435
- def prepared_dependency_files(remove_git_source:, unlock_requirement:,
436
- latest_allowable_version: nil)
439
+ def prepared_dependency_files(
440
+ remove_git_source:,
441
+ unlock_requirement:,
442
+ latest_allowable_version: nil
443
+ )
437
444
  FilePreparer.new(
438
445
  dependency: dependency,
439
446
  dependency_files: dependency_files,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.333.0
4
+ version: 0.335.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.333.0
18
+ version: 0.335.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.333.0
25
+ version: 0.335.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: parallel
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -127,56 +127,56 @@ dependencies:
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '1.67'
130
+ version: '1.80'
131
131
  type: :development
132
132
  prerelease: false
133
133
  version_requirements: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '1.67'
137
+ version: '1.80'
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: rubocop-performance
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '1.22'
144
+ version: '1.26'
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: '1.22'
151
+ version: '1.26'
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: rubocop-rspec
154
154
  requirement: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
- version: '2.29'
158
+ version: '3.7'
159
159
  type: :development
160
160
  prerelease: false
161
161
  version_requirements: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: '2.29'
165
+ version: '3.7'
166
166
  - !ruby/object:Gem::Dependency
167
167
  name: rubocop-sorbet
168
168
  requirement: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '0.8'
172
+ version: '0.10'
173
173
  type: :development
174
174
  prerelease: false
175
175
  version_requirements: !ruby/object:Gem::Requirement
176
176
  requirements:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: '0.8'
179
+ version: '0.10'
180
180
  - !ruby/object:Gem::Dependency
181
181
  name: simplecov
182
182
  requirement: !ruby/object:Gem::Requirement
@@ -322,7 +322,7 @@ licenses:
322
322
  - MIT
323
323
  metadata:
324
324
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
325
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.333.0
325
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.335.0
326
326
  rdoc_options: []
327
327
  require_paths:
328
328
  - lib