dependabot-npm_and_yarn 0.302.0 → 0.304.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.
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -27,9 +27,9 @@ module Dependabot
27
27
 
28
28
  require_relative "latest_version_finder"
29
29
 
30
- TIGHTLY_COUPLED_MONOREPOS = {
30
+ TIGHTLY_COUPLED_MONOREPOS = T.let({
31
31
  "vue" => %w(vue vue-template-compiler)
32
- }.freeze
32
+ }.freeze, T::Hash[String, T::Array[String]])
33
33
 
34
34
  # Error message returned by `yarn add` (for Yarn classic):
35
35
  # " > @reach/router@1.2.1" has incorrect peer dependency "react@15.x || 16.x || 16.4.0-alpha.0911da3"
@@ -91,19 +91,57 @@ module Dependabot
91
91
  npm\s(?:WARN|ERR!)\speer\s(?<required_dep>\S+@\S+(\s\S+)?)\sfrom\s(?<requiring_dep>\S+@\S+)
92
92
  /x
93
93
 
94
- def initialize(dependency:, credentials:, dependency_files:,
95
- latest_allowable_version:, latest_version_finder:, repo_contents_path:, dependency_group: nil)
94
+ sig do
95
+ params(
96
+ dependency: Dependabot::Dependency,
97
+ dependency_files: T::Array[Dependabot::DependencyFile],
98
+ credentials: T::Array[Dependabot::Credential],
99
+ latest_allowable_version: T.nilable(T.any(String, Gem::Version)),
100
+ latest_version_finder: T.any(LatestVersionFinder, PackageLatestVersionFinder),
101
+ repo_contents_path: T.nilable(String),
102
+ dependency_group: T.nilable(Dependabot::DependencyGroup),
103
+ raise_on_ignored: T::Boolean,
104
+ update_cooldown: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
105
+ ).void
106
+ end
107
+ def initialize( # rubocop:disable Metrics/AbcSize
108
+ dependency:, dependency_files:, credentials:,
109
+ latest_allowable_version:, latest_version_finder:,
110
+ repo_contents_path:, dependency_group: nil,
111
+ raise_on_ignored: false, update_cooldown: nil
112
+ )
96
113
  @dependency = dependency
97
- @credentials = credentials
98
114
  @dependency_files = dependency_files
115
+ @credentials = credentials
99
116
  @latest_allowable_version = latest_allowable_version
100
117
  @dependency_group = dependency_group
101
118
 
102
- @latest_version_finder = {}
119
+ @latest_version_finder = T.let(
120
+ {},
121
+ T::Hash[Dependabot::Dependency, T.any(LatestVersionFinder, PackageLatestVersionFinder)
122
+ ]
123
+ )
103
124
  @latest_version_finder[dependency] = latest_version_finder
104
125
  @repo_contents_path = repo_contents_path
105
- end
106
-
126
+ @raise_on_ignored = raise_on_ignored
127
+ @update_cooldown = update_cooldown
128
+
129
+ @types_package = T.let(nil, T.nilable(Dependabot::Dependency))
130
+ @original_package = T.let(nil, T.nilable(Dependabot::Dependency))
131
+ @latest_types_package_version = T.let(nil, T.nilable(Dependabot::Version))
132
+ @dependency_files_builder = T.let(nil, T.nilable(DependencyFilesBuilder))
133
+ # @latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
134
+ @resolve_latest_previous_version = T.let({}, T::Hash[Dependabot::Dependency, T.nilable(String)])
135
+ @paths_requiring_update_check = T.let(nil, T.nilable(T::Array[String]))
136
+ @top_level_dependencies = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
137
+ # @peer_dependency_errors_checked = T.let(false, T::Boolean)
138
+ @old_peer_dependency_errors = T.let(
139
+ nil, T.nilable(T::Array[T.any(T::Hash[String, T.nilable(String)], String)])
140
+ )
141
+ @peer_dependency_errors = T.let(nil, T.nilable(T::Array[T.any(T::Hash[String, T.nilable(String)], String)]))
142
+ end
143
+
144
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
107
145
  def latest_resolvable_version
108
146
  return latest_allowable_version if git_dependency?(dependency)
109
147
  return if part_of_tightly_locked_monorepo?
@@ -115,17 +153,24 @@ module Dependabot
115
153
  satisfying_versions.first
116
154
  end
117
155
 
156
+ sig { returns(T::Boolean) }
118
157
  def latest_version_resolvable_with_full_unlock?
119
158
  return false if dependency_updates_from_full_unlock.nil?
120
159
 
121
160
  true
122
161
  end
123
162
 
163
+ sig do
164
+ params(
165
+ updated_version: T.nilable(T.any(String, Gem::Version))
166
+ ).returns(T.nilable(T.any(String, Gem::Version)))
167
+ end
124
168
  def latest_resolvable_previous_version(updated_version)
125
169
  resolve_latest_previous_version(dependency, updated_version)
126
170
  end
127
171
 
128
172
  # rubocop:disable Metrics/PerceivedComplexity
173
+ sig { returns(T.nilable(T::Array[T::Hash[String, T.nilable(String)]])) }
129
174
  def dependency_updates_from_full_unlock
130
175
  return if git_dependency?(dependency)
131
176
  return updated_monorepo_dependencies if part_of_tightly_locked_monorepo?
@@ -168,28 +213,61 @@ module Dependabot
168
213
 
169
214
  sig { returns(Dependabot::Dependency) }
170
215
  attr_reader :dependency
171
- attr_reader :credentials
216
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
172
217
  attr_reader :dependency_files
218
+ sig { returns(T::Array[Dependabot::Credential]) }
219
+ attr_reader :credentials
220
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
173
221
  attr_reader :latest_allowable_version
222
+ sig { returns(T.nilable(String)) }
174
223
  attr_reader :repo_contents_path
224
+ sig { returns(T.nilable(Dependabot::DependencyGroup)) }
175
225
  attr_reader :dependency_group
226
+ sig { returns(T.nilable(Dependabot::Package::ReleaseCooldownOptions)) }
227
+ attr_reader :update_cooldown
228
+ sig { returns(T::Boolean) }
229
+ attr_reader :raise_on_ignored
176
230
 
231
+ sig { params(dep: Dependabot::Dependency) .returns(T.any(LatestVersionFinder, PackageLatestVersionFinder)) }
177
232
  def latest_version_finder(dep)
178
233
  @latest_version_finder[dep] ||=
179
- LatestVersionFinder.new(
180
- dependency: dep,
181
- credentials: credentials,
182
- dependency_files: dependency_files,
183
- ignored_versions: [],
184
- security_advisories: []
185
- )
234
+ if enable_cooldown?
235
+ PackageLatestVersionFinder.new(
236
+ dependency: dep,
237
+ dependency_files: dependency_files,
238
+ credentials: credentials,
239
+ cooldown_options: update_cooldown,
240
+ ignored_versions: [],
241
+ security_advisories: [],
242
+ raise_on_ignored: raise_on_ignored
243
+ )
244
+ else
245
+ LatestVersionFinder.new(
246
+ dependency: dep,
247
+ credentials: credentials,
248
+ dependency_files: dependency_files,
249
+ ignored_versions: [],
250
+ security_advisories: [],
251
+ raise_on_ignored: raise_on_ignored
252
+ )
253
+ end
254
+ end
255
+
256
+ sig { returns(T::Boolean) }
257
+ def enable_cooldown?
258
+ Dependabot::Experiments.enabled?(:enable_cooldown_for_npm_and_yarn)
186
259
  end
187
260
 
188
261
  # rubocop:disable Metrics/PerceivedComplexity
262
+ sig do
263
+ params(
264
+ dep: Dependabot::Dependency,
265
+ updated_version: T.nilable(T.any(String, Gem::Version))
266
+ ).returns(T.nilable(String))
267
+ end
189
268
  def resolve_latest_previous_version(dep, updated_version)
190
269
  return dep.version if dep.version
191
270
 
192
- @resolve_latest_previous_version ||= {}
193
271
  @resolve_latest_previous_version[dep] ||= begin
194
272
  relevant_versions = latest_version_finder(dependency)
195
273
  .possible_previous_versions_with_details
@@ -220,6 +298,7 @@ module Dependabot
220
298
  end
221
299
  # rubocop:enable Metrics/PerceivedComplexity
222
300
 
301
+ sig { returns(T::Boolean) }
223
302
  def part_of_tightly_locked_monorepo?
224
303
  monorepo_dep_names =
225
304
  TIGHTLY_COUPLED_MONOREPOS.values
@@ -233,6 +312,7 @@ module Dependabot
233
312
  deps_to_update.count > 1
234
313
  end
235
314
 
315
+ sig { returns(T::Array[T::Hash[String, T.nilable(String)]]) }
236
316
  def updated_monorepo_dependencies
237
317
  monorepo_dep_names =
238
318
  TIGHTLY_COUPLED_MONOREPOS.values
@@ -240,7 +320,7 @@ module Dependabot
240
320
 
241
321
  deps_to_update =
242
322
  top_level_dependencies
243
- .select { |d| monorepo_dep_names.include?(d.name) }
323
+ .select { |d| monorepo_dep_names&.include?(d.name) }
244
324
 
245
325
  updates = []
246
326
  deps_to_update.each do |dep|
@@ -266,48 +346,71 @@ module Dependabot
266
346
  updates
267
347
  end
268
348
 
349
+ sig { returns(T.nilable(Dependabot::Dependency)) }
269
350
  def types_package
270
- @types_package ||= begin
351
+ return @types_package if @types_package
352
+
353
+ @types_package = begin
271
354
  types_package_name = PackageName.new(dependency.name).types_package_name
272
355
  top_level_dependencies.find { |d| types_package_name.to_s == d.name } if types_package_name
273
356
  end
357
+ @types_package
274
358
  end
275
359
 
360
+ sig { returns(T.nilable(Dependabot::Dependency)) }
276
361
  def original_package
277
- @original_package ||= begin
362
+ return @original_package if @original_package
363
+
364
+ @original_package = begin
278
365
  original_package_name = PackageName.new(dependency.name).library_name
279
366
  top_level_dependencies.find { |d| original_package_name.to_s == d.name } if original_package_name
280
367
  end
368
+ @original_package
281
369
  end
282
370
 
371
+ sig { returns(T.nilable(Dependabot::Version)) }
283
372
  def latest_types_package_version
284
- @latest_types_package_version ||= latest_version_finder(types_package).latest_version_from_registry
373
+ types_pkg = types_package
374
+ return unless types_pkg
375
+
376
+ return @latest_types_package_version if @latest_types_package_version
377
+
378
+ @latest_types_package_version = latest_version_finder(types_pkg).latest_version_from_registry
379
+ @latest_types_package_version
285
380
  end
286
381
 
382
+ sig { returns(T::Boolean) }
287
383
  def types_update_available?
288
- return false if types_package.nil?
384
+ types_pkg = types_package
385
+ return false unless types_pkg
289
386
 
290
- return false if latest_types_package_version.nil?
387
+ latest_types_version = latest_types_package_version
388
+ return false unless latest_types_version
291
389
 
292
- return false unless latest_allowable_version.backwards_compatible_with?(latest_types_package_version)
390
+ latest_allowable_ver = latest_allowable_version
391
+ return false unless latest_allowable_ver.is_a?(Version) && latest_allowable_ver.backwards_compatible_with?(
392
+ T.unsafe(latest_types_version)
393
+ )
293
394
 
294
- return false unless version_class.correct?(types_package.version)
395
+ return false unless version_class.correct?(types_pkg.version)
295
396
 
296
- current_types_package_version = version_class.new(types_package.version)
397
+ current_types_package_version = version_class.new(types_pkg.version)
297
398
 
298
- return false unless current_types_package_version < latest_types_package_version
399
+ return false unless current_types_package_version < latest_types_version
299
400
 
300
401
  true
301
402
  end
302
403
 
404
+ sig { returns(T::Boolean) }
303
405
  def original_package_update_available?
304
- return false if original_package.nil?
406
+ original_pack = original_package
407
+ return false unless original_pack
305
408
 
306
- return false unless version_class.correct?(original_package.version)
409
+ return false unless version_class.correct?(original_pack.version)
307
410
 
308
- original_package_version = version_class.new(original_package.version)
411
+ original_package_version = version_class.new(original_pack.version)
309
412
 
310
- latest_version = latest_version_finder(original_package).latest_version_from_registry
413
+ latest_version = latest_version_finder(original_pack).latest_version_from_registry
311
414
 
312
415
  # If the latest version is within the scope of the current requirements,
313
416
  # latest_version will be nil. In such cases, there is no update available.
@@ -316,41 +419,45 @@ module Dependabot
316
419
  original_package_version < latest_version
317
420
  end
318
421
 
422
+ sig { returns(T::Array[T::Hash[String, T.nilable(String)]]) }
319
423
  def updated_types_dependencies
320
424
  [{
321
425
  dependency: types_package,
322
426
  version: latest_types_package_version,
323
427
  previous_version: resolve_latest_previous_version(
324
- types_package, latest_types_package_version
428
+ T.must(types_package), T.cast(latest_types_package_version, Gem::Version)
325
429
  )
326
430
  }]
327
431
  end
328
432
 
433
+ sig { returns(T::Array[T.any(T::Hash[String, T.nilable(String)], String)]) }
329
434
  def peer_dependency_errors
330
- return @peer_dependency_errors if @peer_dependency_errors_checked
331
-
332
- @peer_dependency_errors_checked = true
435
+ return @peer_dependency_errors if @peer_dependency_errors
333
436
 
334
- @peer_dependency_errors =
335
- fetch_peer_dependency_errors(version: latest_allowable_version)
437
+ @peer_dependency_errors = fetch_peer_dependency_errors(version: latest_allowable_version)
438
+ @peer_dependency_errors
336
439
  end
337
440
 
441
+ sig { returns(T::Array[T.any(T::Hash[String, T.nilable(String)], String)]) }
338
442
  def old_peer_dependency_errors
339
- return @old_peer_dependency_errors if @old_peer_dependency_errors_checked
340
-
341
- @old_peer_dependency_errors_checked = true
443
+ return @old_peer_dependency_errors if @old_peer_dependency_errors
342
444
 
343
445
  version = version_for_dependency(dependency)
344
446
 
345
- @old_peer_dependency_errors =
346
- fetch_peer_dependency_errors(version: version)
447
+ @old_peer_dependency_errors = fetch_peer_dependency_errors(version: version)
448
+ @old_peer_dependency_errors
347
449
  end
348
450
 
451
+ sig do
452
+ params(
453
+ version: T.nilable(T.any(String, Gem::Version))
454
+ ).returns(T::Array[T.any(T::Hash[String, T.nilable(String)], String)])
455
+ end
349
456
  def fetch_peer_dependency_errors(version:)
350
457
  # TODO: Add all of the error handling that the FileUpdater does
351
458
  # here (since problematic repos will be resolved here before they're
352
459
  # seen by the FileUpdater)
353
- base_dir = dependency_files.first.directory
460
+ base_dir = T.must(dependency_files.first).directory
354
461
  SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
355
462
  dependency_files_builder.write_temporary_dependency_files
356
463
 
@@ -402,16 +509,22 @@ module Dependabot
402
509
  end
403
510
  # rubocop:enable Metrics/AbcSize
404
511
 
512
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
405
513
  def unmet_peer_dependencies
406
514
  peer_dependency_errors
407
515
  .map { |captures| error_details_from_captures(captures) }
408
516
  end
409
517
 
518
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
410
519
  def old_unmet_peer_dependencies
411
520
  old_peer_dependency_errors
412
521
  .map { |captures| error_details_from_captures(captures) }
413
522
  end
414
523
 
524
+ sig do
525
+ params(captures: T.any(T::Hash[String, T.nilable(String)], String))
526
+ .returns(T::Hash[Symbol, T.nilable(String)])
527
+ end
415
528
  def error_details_from_captures(captures)
416
529
  return {} unless captures.is_a?(Hash)
417
530
 
@@ -421,12 +534,13 @@ module Dependabot
421
534
 
422
535
  {
423
536
  requirement_name: required_dep_captures.sub(/@[^@]+$/, ""),
424
- requirement_version: required_dep_captures.split("@").last.delete('"'),
537
+ requirement_version: required_dep_captures.split("@").last&.delete('"'),
425
538
  requiring_dep_name: requiring_dep_captures.sub(/@[^@]+$/, "")
426
539
  }
427
540
  end
428
541
 
429
- def relevant_unmet_peer_dependencies
542
+ sig { returns(T::Array[T::Hash[Symbol, T.nilable(String)]]) }
543
+ def relevant_unmet_peer_dependencies # rubocop:disable Metrics/PerceivedComplexity
430
544
  relevant_unmet_peer_dependencies =
431
545
  unmet_peer_dependencies.select do |dep|
432
546
  dep[:requirement_name] == dependency.name ||
@@ -437,7 +551,7 @@ module Dependabot
437
551
  # Ignore unmet peer dependencies that are in the dependency group because
438
552
  # the update is also updating those dependencies.
439
553
  relevant_unmet_peer_dependencies.reject! do |dep|
440
- dependency_group.dependencies.any? do |group_dep|
554
+ dependency_group&.dependencies&.any? do |group_dep|
441
555
  dep[:requirement_name] == group_dep.name ||
442
556
  dep[:requiring_dep_name] == group_dep.name
443
557
  end
@@ -456,11 +570,13 @@ module Dependabot
456
570
  end
457
571
 
458
572
  # rubocop:disable Metrics/PerceivedComplexity
573
+ sig { returns(T::Array[T.any(String, Gem::Version)]) }
459
574
  def satisfying_versions
460
575
  latest_version_finder(dependency)
461
576
  .possible_versions_with_details
462
- .select do |version, details|
463
- next false unless satisfies_peer_reqs_on_dep?(version)
577
+ .select do |versions_with_details|
578
+ version, details = versions_with_details
579
+ next false unless satisfies_peer_reqs_on_dep?(T.unsafe(version))
464
580
  next true unless details["peerDependencies"]
465
581
  next true if version == version_for_dependency(dependency)
466
582
 
@@ -476,18 +592,22 @@ module Dependabot
476
592
  rescue Gem::Requirement::BadRequirementError
477
593
  false
478
594
  end
595
+ end.map do |versions_with_details| # rubocop:disable Style/MultilineBlockChain
596
+ # Return just the version
597
+ version, = versions_with_details
598
+ version
479
599
  end
480
- .map(&:first)
481
600
  end
482
601
 
483
602
  # rubocop:enable Metrics/PerceivedComplexity
484
603
 
604
+ sig { params(version: T.nilable(T.any(String, Gem::Version))).returns(T::Boolean) }
485
605
  def satisfies_peer_reqs_on_dep?(version)
486
606
  newly_broken_peer_reqs_on_dep.all? do |peer_req|
487
607
  req = peer_req.fetch(:requirement_version)
488
608
 
489
609
  # Git requirements can't be satisfied by a version
490
- next false if req.include?("/")
610
+ next false if req&.include?("/")
491
611
 
492
612
  reqs = requirement_class.requirements_array(req)
493
613
  reqs.any? { |r| r.satisfied_by?(version) }
@@ -496,11 +616,16 @@ module Dependabot
496
616
  end
497
617
  end
498
618
 
499
- def latest_version_of_dep_with_satisfied_peer_reqs(dep)
500
- latest_version_finder(dep)
619
+ sig { params(dep: Dependabot::Dependency).returns(T.nilable(T.any(String, Gem::Version))) }
620
+ def latest_version_of_dep_with_satisfied_peer_reqs(dep) # rubocop:disable Metrics/PerceivedComplexity
621
+ dependency_version = version_for_dependency(dep)
622
+ version_with_detail =
623
+ latest_version_finder(dep)
501
624
  .possible_versions_with_details
502
- .find do |version, details|
503
- next false unless version > version_for_dependency(dep)
625
+ .find do |version_details|
626
+ version, details = version_details
627
+
628
+ next false unless !dependency_version || version > dependency_version
504
629
  next true unless details["peerDependencies"]
505
630
 
506
631
  details["peerDependencies"].all? do |peer_dep_name, req|
@@ -515,9 +640,10 @@ module Dependabot
515
640
  false
516
641
  end
517
642
  end
518
- &.first
643
+ version_with_detail.is_a?(Array) ? version_with_detail.first : version_with_detail
519
644
  end
520
645
 
646
+ sig { params(dep: Dependabot::Dependency).returns(T::Boolean) }
521
647
  def git_dependency?(dep)
522
648
  # ignored_version/raise_on_ignored are irrelevant.
523
649
  GitCommitChecker
@@ -525,22 +651,36 @@ module Dependabot
525
651
  .git_dependency?
526
652
  end
527
653
 
654
+ sig { returns(T::Array[T::Hash[Symbol, T.nilable(String)]]) }
528
655
  def newly_broken_peer_reqs_on_dep
529
656
  relevant_unmet_peer_dependencies
530
657
  .select { |dep| dep[:requirement_name] == dependency.name }
531
658
  end
532
659
 
660
+ sig { returns(T::Array[T::Hash[Symbol, T.nilable(String)]]) }
533
661
  def newly_broken_peer_reqs_from_dep
534
662
  relevant_unmet_peer_dependencies
535
663
  .select { |dep| dep[:requiring_dep_name] == dependency.name }
536
664
  end
537
665
 
666
+ sig do
667
+ params(
668
+ lockfiles: T::Array[Dependabot::DependencyFile],
669
+ path: String
670
+ ).returns(T::Array[Dependabot::DependencyFile])
671
+ end
538
672
  def lockfiles_for_path(lockfiles:, path:)
539
673
  lockfiles.select do |lockfile|
540
674
  File.dirname(lockfile.name) == File.dirname(path)
541
675
  end
542
676
  end
543
677
 
678
+ sig do
679
+ params(
680
+ path: String,
681
+ version: T.nilable(T.any(String, Gem::Version))
682
+ ).returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]])))
683
+ end
544
684
  def run_checker(path:, version:)
545
685
  yarn_lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.yarn_locks, path: path)
546
686
  return run_yarn_checker(path: path, version: version, lockfile: yarn_lockfiles.first) if yarn_lockfiles.any?
@@ -568,12 +708,25 @@ module Dependabot
568
708
  handle_peer_dependency_errors(e.message)
569
709
  end
570
710
 
711
+ sig do
712
+ params(
713
+ path: String,
714
+ version: T.nilable(T.any(String, Gem::Version)),
715
+ lockfile: T.nilable(Dependabot::DependencyFile)
716
+ ).returns(T.untyped)
717
+ end
571
718
  def run_yarn_checker(path:, version:, lockfile:)
572
719
  return run_yarn_berry_checker(path: path, version: version) if Helpers.yarn_berry?(lockfile)
573
720
 
574
721
  run_yarn_classic_checker(path: path, version: version)
575
722
  end
576
723
 
724
+ sig do
725
+ params(
726
+ path: String,
727
+ version: T.nilable(T.any(String, Gem::Version))
728
+ ).returns(T.untyped)
729
+ end
577
730
  def run_pnpm_checker(path:, version:)
578
731
  SharedHelpers.with_git_configured(credentials: credentials) do
579
732
  Dir.chdir(path) do
@@ -591,6 +744,12 @@ module Dependabot
591
744
  end
592
745
  end
593
746
 
747
+ sig do
748
+ params(
749
+ path: String,
750
+ version: T.nilable(T.any(String, Gem::Version))
751
+ ).returns(T.untyped)
752
+ end
594
753
  def run_bun_checker(path:, version:)
595
754
  SharedHelpers.with_git_configured(credentials: credentials) do
596
755
  Dir.chdir(path) do
@@ -602,6 +761,12 @@ module Dependabot
602
761
  end
603
762
  end
604
763
 
764
+ sig do
765
+ params(
766
+ path: String,
767
+ version: T.nilable(T.any(String, Gem::Version))
768
+ ).returns(T.untyped)
769
+ end
605
770
  def run_yarn_berry_checker(path:, version:)
606
771
  # This method mimics calling a native helper in order to comply with the caller's expectations
607
772
  # Specifically we add the dependency at the specified updated version
@@ -623,6 +788,12 @@ module Dependabot
623
788
  end
624
789
  end
625
790
 
791
+ sig do
792
+ params(
793
+ path: String,
794
+ version: T.nilable(T.any(String, Gem::Version))
795
+ ).returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]])))
796
+ end
626
797
  def run_yarn_classic_checker(path:, version:)
627
798
  SharedHelpers.with_git_configured(credentials: credentials) do
628
799
  Dir.chdir(path) do
@@ -632,7 +803,7 @@ module Dependabot
632
803
  args: [
633
804
  Dir.pwd,
634
805
  dependency.name,
635
- version,
806
+ T.unsafe(version),
636
807
  requirements_for_path(dependency.requirements, path)
637
808
  ]
638
809
  )
@@ -640,6 +811,12 @@ module Dependabot
640
811
  end
641
812
  end
642
813
 
814
+ sig do
815
+ params(
816
+ path: String,
817
+ version: T.nilable(T.any(String, Gem::Version))
818
+ ).returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]])))
819
+ end
643
820
  def run_npm_checker(path:, version:)
644
821
  SharedHelpers.with_git_configured(credentials: credentials) do
645
822
  Dir.chdir(path) do
@@ -656,7 +833,7 @@ module Dependabot
656
833
  args: [
657
834
  Dir.pwd,
658
835
  dependency.name,
659
- version,
836
+ T.unsafe(version),
660
837
  requirements_for_path(dependency.requirements, path),
661
838
  top_level_dependencies.map(&:to_h)
662
839
  ]
@@ -665,6 +842,11 @@ module Dependabot
665
842
  end
666
843
  end
667
844
 
845
+ sig do
846
+ params(
847
+ version: T.nilable(T.any(String, Gem::Version))
848
+ ).returns(T.nilable(T.any(T::Hash[String, T.untyped], String, T::Array[T::Hash[String, T.untyped]])))
849
+ end
668
850
  def run_npm8_checker(version:)
669
851
  cmd =
670
852
  "install #{version_install_arg(version: version)} --package-lock-only --dry-run=true --ignore-scripts"
@@ -677,6 +859,11 @@ module Dependabot
677
859
  raise if e.message.match?(NPM8_PEER_DEP_ERROR_REGEX)
678
860
  end
679
861
 
862
+ sig do
863
+ params(
864
+ version: T.nilable(T.any(String, Gem::Version))
865
+ ).returns(String)
866
+ end
680
867
  def version_install_arg(version:)
681
868
  git_source = dependency.requirements.find { |req| req[:source] && req[:source][:type] == "git" }
682
869
 
@@ -687,6 +874,12 @@ module Dependabot
687
874
  end
688
875
  end
689
876
 
877
+ sig do
878
+ params(
879
+ requirements: T::Array[T::Hash[Symbol, T.untyped]],
880
+ path: String
881
+ ).returns(T::Array[T::Hash[Symbol, T.untyped]])
882
+ end
690
883
  def requirements_for_path(requirements, path)
691
884
  return requirements if path.to_s == "."
692
885
 
@@ -700,31 +893,44 @@ module Dependabot
700
893
  # Top level dependencies are required in the peer dep checker
701
894
  # to fetch the manifests for all top level deps which may contain
702
895
  # "peerDependency" requirements
896
+ sig { returns(T::Array[Dependabot::Dependency]) }
703
897
  def top_level_dependencies
704
- @top_level_dependencies ||= NpmAndYarn::FileParser.new(
898
+ return @top_level_dependencies if @top_level_dependencies
899
+
900
+ @top_level_dependencies = NpmAndYarn::FileParser.new(
705
901
  dependency_files: dependency_files,
706
902
  source: nil,
707
903
  credentials: credentials
708
904
  ).parse.select(&:top_level?)
905
+ @top_level_dependencies
709
906
  end
710
907
 
908
+ sig { returns(T::Array[String]) }
711
909
  def paths_requiring_update_check
712
- @paths_requiring_update_check ||=
910
+ return @paths_requiring_update_check if @paths_requiring_update_check
911
+
912
+ @paths_requiring_update_check =
713
913
  DependencyFilesFilterer.new(
714
914
  dependency_files: dependency_files,
715
915
  updated_dependencies: [dependency]
716
916
  ).paths_requiring_update_check
917
+ @paths_requiring_update_check
717
918
  end
718
919
 
920
+ sig { returns(DependencyFilesBuilder) }
719
921
  def dependency_files_builder
720
- @dependency_files_builder ||=
922
+ return @dependency_files_builder if @dependency_files_builder
923
+
924
+ @dependency_files_builder =
721
925
  DependencyFilesBuilder.new(
722
926
  dependency: dependency,
723
927
  dependency_files: dependency_files,
724
928
  credentials: credentials
725
929
  )
930
+ @dependency_files_builder
726
931
  end
727
932
 
933
+ sig { params(dep: Dependabot::Dependency).returns(T.nilable(T.any(String, Gem::Version))) }
728
934
  def version_for_dependency(dep)
729
935
  return version_class.new(dep.version) if dep.version && version_class.correct?(dep.version)
730
936
 
@@ -737,14 +943,17 @@ module Dependabot
737
943
  .max
738
944
  end
739
945
 
946
+ sig { returns(T.class_of(Dependabot::Version)) }
740
947
  def version_class
741
948
  dependency.version_class
742
949
  end
743
950
 
951
+ sig { returns(T.class_of(Dependabot::Requirement)) }
744
952
  def requirement_class
745
953
  dependency.requirement_class
746
954
  end
747
955
 
956
+ sig { returns(String) }
748
957
  def version_regex
749
958
  Dependabot::NpmAndYarn::Version::VERSION_PATTERN
750
959
  end