dependabot-bun 0.321.2 → 0.322.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46499cefe8115a9506d33a7246f6c5cd16519b1be78532117baf9df95d4fd07b
|
4
|
+
data.tar.gz: 7de2f41d26d85efda5d73ee4ecc752d134ad26237acb463a6af11a620794e9f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1bec3ed1b2e310cbae6cfb7e4ca995d689b53d6af94f41f97cc21b38bb5ba654ee27342fd39aa4ff3772856ef7af6016d9ad9327fac54d7631d338a953ac52a
|
7
|
+
data.tar.gz: fb33aeb0a072aa7ade8c6b10f179a0a66c31dc2d8eb1bed511381a4e0ddb1de27bc8a5ae13b11650d7aad63e3665d417cf66fce3f4617b9ebe891d5888a37e83
|
@@ -173,13 +173,11 @@ module Dependabot
|
|
173
173
|
|
174
174
|
package_type = infer_package_type(details)
|
175
175
|
|
176
|
-
deprecated = fetch_value_from_hash(details, RELEASE_DEPRECATION_KEY)
|
177
|
-
|
178
176
|
Dependabot::Package::PackageRelease.new(
|
179
177
|
version: Version.new(version),
|
180
178
|
released_at: time_data[version] ? Time.parse(time_data[version]) : nil,
|
181
|
-
yanked:
|
182
|
-
yanked_reason:
|
179
|
+
yanked: false,
|
180
|
+
yanked_reason: nil,
|
183
181
|
downloads: nil,
|
184
182
|
latest: latest_version.to_s == version,
|
185
183
|
url: package_version_url(version),
|
@@ -74,12 +74,14 @@ module Dependabot
|
|
74
74
|
override.params(language_version: T.nilable(T.any(String, Dependabot::Version)))
|
75
75
|
.returns(T.nilable(Dependabot::Version))
|
76
76
|
end
|
77
|
-
def latest_version_with_no_unlock(language_version: nil)
|
77
|
+
def latest_version_with_no_unlock(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
|
78
78
|
with_custom_registry_rescue do
|
79
79
|
return unless valid_npm_details?
|
80
80
|
return version_from_dist_tags&.version if specified_dist_tag_requirement?
|
81
81
|
|
82
|
-
|
82
|
+
releases = possible_releases
|
83
|
+
in_range_versions = filter_out_of_range_versions(releases)
|
84
|
+
in_range_versions.find { |r| !yanked_version?(r.version) }&.version
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
@@ -96,7 +98,7 @@ module Dependabot
|
|
96
98
|
params(language_version: T.nilable(T.any(String, Dependabot::Version)))
|
97
99
|
.returns(T.nilable(Dependabot::Version))
|
98
100
|
end
|
99
|
-
def fetch_latest_version(language_version: nil)
|
101
|
+
def fetch_latest_version(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
|
100
102
|
with_custom_registry_rescue do
|
101
103
|
return unless valid_npm_details?
|
102
104
|
|
@@ -105,7 +107,7 @@ module Dependabot
|
|
105
107
|
|
106
108
|
return if specified_dist_tag_requirement?
|
107
109
|
|
108
|
-
|
110
|
+
possible_releases.find { |r| !yanked_version?(r.version) }&.version
|
109
111
|
end
|
110
112
|
end
|
111
113
|
|
@@ -114,65 +116,16 @@ module Dependabot
|
|
114
116
|
.params(language_version: T.nilable(T.any(String, Dependabot::Version)))
|
115
117
|
.returns(T.nilable(Dependabot::Version))
|
116
118
|
end
|
117
|
-
def fetch_latest_version_with_no_unlock(language_version: nil)
|
119
|
+
def fetch_latest_version_with_no_unlock(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
|
118
120
|
with_custom_registry_rescue do
|
119
121
|
return unless valid_npm_details?
|
120
122
|
return version_from_dist_tags&.version if specified_dist_tag_requirement?
|
121
123
|
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
sig do
|
127
|
-
override
|
128
|
-
.params(releases: T::Array[Dependabot::Package::PackageRelease])
|
129
|
-
.returns(T::Array[Dependabot::Package::PackageRelease])
|
130
|
-
end
|
131
|
-
def apply_post_fetch_latest_versions_filter(releases)
|
132
|
-
original_count = releases.count
|
133
|
-
filtered_versions = lazy_filter_yanked_versions_by_min_max(releases, check_max: true)
|
124
|
+
releases = possible_releases
|
134
125
|
|
135
|
-
|
136
|
-
|
137
|
-
Dependabot.logger.info(
|
138
|
-
"Filtered out #{original_count - filtered_versions.count} " \
|
139
|
-
"yanked (not found) versions after fetching latest versions"
|
140
|
-
)
|
126
|
+
in_range_versions = filter_out_of_range_versions(releases)
|
127
|
+
in_range_versions.find { |r| !yanked_version?(r.version) }&.version
|
141
128
|
end
|
142
|
-
|
143
|
-
filtered_versions
|
144
|
-
end
|
145
|
-
|
146
|
-
sig do
|
147
|
-
params(
|
148
|
-
releases: T::Array[Dependabot::Package::PackageRelease],
|
149
|
-
check_max: T::Boolean
|
150
|
-
).returns(T::Array[Dependabot::Package::PackageRelease])
|
151
|
-
end
|
152
|
-
def lazy_filter_yanked_versions_by_min_max(releases, check_max: true)
|
153
|
-
# Sort the versions based on the check_max flag (max -> descending, min -> ascending)
|
154
|
-
sorted_releases = if check_max
|
155
|
-
releases.sort_by(&:version).reverse
|
156
|
-
else
|
157
|
-
releases.sort_by(&:version)
|
158
|
-
end
|
159
|
-
|
160
|
-
filtered_versions = []
|
161
|
-
|
162
|
-
not_yanked = T.let(false, T::Boolean)
|
163
|
-
|
164
|
-
# Iterate through the sorted versions lazily, filtering out yanked versions
|
165
|
-
sorted_releases.each do |release|
|
166
|
-
next if !not_yanked && yanked_version?(release.version)
|
167
|
-
|
168
|
-
not_yanked = true
|
169
|
-
|
170
|
-
# Once we find a valid (non-yanked) version, add it to the filtered list
|
171
|
-
filtered_versions << release
|
172
|
-
break
|
173
|
-
end
|
174
|
-
|
175
|
-
filtered_versions
|
176
129
|
end
|
177
130
|
|
178
131
|
sig do
|
@@ -200,11 +153,10 @@ module Dependabot
|
|
200
153
|
secure_versions = filter_ignored_versions(secure_versions)
|
201
154
|
secure_versions = filter_lower_versions(secure_versions)
|
202
155
|
|
203
|
-
#
|
204
|
-
secure_versions
|
205
|
-
|
206
|
-
|
207
|
-
secure_versions.max_by(&:version)&.version
|
156
|
+
# Find first non-yanked version
|
157
|
+
secure_versions.sort_by(&:version).find do |version|
|
158
|
+
!yanked_version?(version.version)
|
159
|
+
end&.version
|
208
160
|
end
|
209
161
|
end
|
210
162
|
|
@@ -213,17 +165,16 @@ module Dependabot
|
|
213
165
|
.returns(T::Array[Dependabot::Package::PackageRelease])
|
214
166
|
end
|
215
167
|
def filter_prerelease_versions(releases)
|
216
|
-
|
168
|
+
releases.reject do |release|
|
217
169
|
release.version.prerelease? && !related_to_current_pre?(release.version)
|
218
170
|
end
|
171
|
+
end
|
219
172
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
filtered
|
173
|
+
sig do
|
174
|
+
override.returns(T.nilable(T::Array[Dependabot::Package::PackageRelease]))
|
175
|
+
end
|
176
|
+
def available_versions
|
177
|
+
possible_releases
|
227
178
|
end
|
228
179
|
|
229
180
|
sig do
|
@@ -271,7 +222,9 @@ module Dependabot
|
|
271
222
|
.returns(T::Array[Dependabot::Package::PackageRelease])
|
272
223
|
end
|
273
224
|
def possible_releases(filter_ignored: true)
|
274
|
-
releases = possible_previous_releases.reject
|
225
|
+
releases = possible_previous_releases.reject do |r|
|
226
|
+
r.details["deprecated"]
|
227
|
+
end
|
275
228
|
|
276
229
|
return filter_releases(releases) if filter_ignored
|
277
230
|
|
@@ -298,13 +251,13 @@ module Dependabot
|
|
298
251
|
sig { returns(T::Array[[Dependabot::Version, T::Hash[String, T.nilable(String)]]]) }
|
299
252
|
def possible_previous_versions_with_details
|
300
253
|
possible_previous_releases.map do |r|
|
301
|
-
[r.version,
|
254
|
+
[r.version, r.details]
|
302
255
|
end
|
303
256
|
end
|
304
257
|
|
305
258
|
sig { override.returns(T::Boolean) }
|
306
259
|
def cooldown_enabled?
|
307
|
-
|
260
|
+
true
|
308
261
|
end
|
309
262
|
|
310
263
|
private
|
@@ -334,20 +287,24 @@ module Dependabot
|
|
334
287
|
.find { |r| dist_tags.include?(r[:requirement]) }
|
335
288
|
&.fetch(:requirement)
|
336
289
|
|
337
|
-
|
290
|
+
# For cooldown filtering, use filtered releases
|
291
|
+
releases = available_versions
|
338
292
|
|
339
293
|
releases = filter_by_cooldown(releases) if releases
|
340
294
|
|
341
295
|
if dist_tag_req
|
342
296
|
release = find_dist_tag_release(dist_tag_req, releases)
|
343
|
-
return release
|
297
|
+
return release unless release&.version && yanked_version?(release.version)
|
344
298
|
end
|
345
299
|
|
346
|
-
|
300
|
+
return nil unless dist_tags["latest"]
|
347
301
|
|
348
|
-
|
302
|
+
latest_version = Version.new(dist_tags["latest"])
|
349
303
|
|
350
|
-
|
304
|
+
if wants_latest_dist_tag?(latest_version)
|
305
|
+
# Find the release object for this version, even if deprecated
|
306
|
+
return possible_previous_releases.find { |r| r.version == latest_version }
|
307
|
+
end
|
351
308
|
|
352
309
|
nil
|
353
310
|
end
|
@@ -440,515 +397,19 @@ module Dependabot
|
|
440
397
|
def yanked_version?(version)
|
441
398
|
package_fetcher.yanked?(version)
|
442
399
|
end
|
443
|
-
end
|
444
|
-
|
445
|
-
class LatestVersionFinder # rubocop:disable Metrics/ClassLength
|
446
|
-
extend T::Sig
|
447
|
-
|
448
|
-
sig do
|
449
|
-
params(
|
450
|
-
dependency: Dependabot::Dependency,
|
451
|
-
dependency_files: T::Array[Dependabot::DependencyFile],
|
452
|
-
credentials: T::Array[Dependabot::Credential],
|
453
|
-
ignored_versions: T::Array[String],
|
454
|
-
security_advisories: T::Array[Dependabot::SecurityAdvisory],
|
455
|
-
raise_on_ignored: T::Boolean
|
456
|
-
).void
|
457
|
-
end
|
458
|
-
def initialize(
|
459
|
-
dependency:,
|
460
|
-
dependency_files:,
|
461
|
-
credentials:,
|
462
|
-
ignored_versions:,
|
463
|
-
security_advisories:,
|
464
|
-
raise_on_ignored: false
|
465
|
-
)
|
466
|
-
@dependency = dependency
|
467
|
-
@credentials = credentials
|
468
|
-
@dependency_files = dependency_files
|
469
|
-
@ignored_versions = ignored_versions
|
470
|
-
@raise_on_ignored = raise_on_ignored
|
471
|
-
@security_advisories = security_advisories
|
472
|
-
|
473
|
-
@possible_previous_versions_with_details = T.let(nil, T.nilable(T::Array[T::Array[T.untyped]]))
|
474
|
-
@yanked = T.let({}, T::Hash[Version, T.nilable(T::Boolean)])
|
475
|
-
@npm_details = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
|
476
|
-
@registry_finder = T.let(nil, T.nilable(Package::RegistryFinder))
|
477
|
-
@version_endpoint_working = T.let(nil, T.nilable(T::Boolean))
|
478
|
-
end
|
479
|
-
|
480
|
-
sig { returns(T.nilable(Version)) }
|
481
|
-
def latest_version_from_registry
|
482
|
-
return unless valid_npm_details?
|
483
|
-
return version_from_dist_tags if version_from_dist_tags
|
484
|
-
return if specified_dist_tag_requirement?
|
485
|
-
|
486
|
-
possible_versions.find { |v| !yanked?(v) }
|
487
|
-
rescue Excon::Error::Socket, Excon::Error::Timeout, RegistryError
|
488
|
-
raise if dependency_registry == "registry.npmjs.org"
|
489
|
-
# Custom registries can be flaky. We don't want to make that
|
490
|
-
# our problem, so we quietly return `nil` here.
|
491
|
-
end
|
492
|
-
|
493
|
-
sig { returns(T.nilable(Version)) }
|
494
|
-
def latest_version_with_no_unlock
|
495
|
-
return unless valid_npm_details?
|
496
|
-
return version_from_dist_tags if specified_dist_tag_requirement?
|
497
|
-
|
498
|
-
in_range_versions = filter_out_of_range_versions(possible_versions)
|
499
|
-
in_range_versions.find { |version| !yanked?(version) }
|
500
|
-
rescue Excon::Error::Socket, Excon::Error::Timeout
|
501
|
-
raise if dependency_registry == "registry.npmjs.org"
|
502
|
-
# Sometimes custom registries are flaky. We don't want to make that
|
503
|
-
# our problem, so we quietly return `nil` here.
|
504
|
-
end
|
505
|
-
|
506
|
-
sig { returns(T.nilable(Version)) }
|
507
|
-
def lowest_security_fix_version
|
508
|
-
return unless valid_npm_details?
|
509
|
-
|
510
|
-
secure_versions =
|
511
|
-
if specified_dist_tag_requirement?
|
512
|
-
[version_from_dist_tags].compact
|
513
|
-
else
|
514
|
-
possible_versions(filter_ignored: false)
|
515
|
-
end
|
516
|
-
|
517
|
-
secure_versions = Dependabot::UpdateCheckers::VersionFilters
|
518
|
-
.filter_vulnerable_versions(
|
519
|
-
secure_versions,
|
520
|
-
security_advisories
|
521
|
-
)
|
522
|
-
secure_versions = filter_ignored_versions(secure_versions)
|
523
|
-
secure_versions = filter_lower_versions(secure_versions)
|
524
|
-
|
525
|
-
secure_versions.reverse.find { |version| !yanked?(version) }
|
526
|
-
rescue Excon::Error::Socket, Excon::Error::Timeout
|
527
|
-
raise if dependency_registry == "registry.npmjs.org"
|
528
|
-
# Sometimes custom registries are flaky. We don't want to make that
|
529
|
-
# our problem, so we quietly return `nil` here.
|
530
|
-
end
|
531
|
-
|
532
|
-
sig { returns(T::Array[T::Array[T.untyped]]) }
|
533
|
-
def possible_previous_versions_with_details # rubocop:disable Metrics/PerceivedComplexity
|
534
|
-
return @possible_previous_versions_with_details if @possible_previous_versions_with_details
|
535
|
-
|
536
|
-
@possible_previous_versions_with_details =
|
537
|
-
npm_details&.fetch("versions", {})
|
538
|
-
&.transform_keys { |k| version_class.new(k) }
|
539
|
-
&.reject do |v, _|
|
540
|
-
v.prerelease? && !related_to_current_pre?(v)
|
541
|
-
end&.sort_by(&:first)&.reverse
|
542
|
-
@possible_previous_versions_with_details
|
543
|
-
end
|
544
400
|
|
545
401
|
sig do
|
546
|
-
params(
|
547
|
-
.returns(T::Array[
|
548
|
-
end
|
549
|
-
def possible_versions_with_details(filter_ignored: true)
|
550
|
-
versions = possible_previous_versions_with_details
|
551
|
-
.reject { |_, details| details["deprecated"] }
|
552
|
-
|
553
|
-
return filter_ignored_versions(versions) if filter_ignored
|
554
|
-
|
555
|
-
versions
|
556
|
-
end
|
557
|
-
|
558
|
-
sig do
|
559
|
-
params(filter_ignored: T::Boolean)
|
560
|
-
.returns(T::Array[Version])
|
561
|
-
end
|
562
|
-
def possible_versions(filter_ignored: true)
|
563
|
-
possible_versions_with_details(filter_ignored: filter_ignored)
|
564
|
-
.map(&:first)
|
565
|
-
end
|
566
|
-
|
567
|
-
private
|
568
|
-
|
569
|
-
sig { returns(Dependabot::Dependency) }
|
570
|
-
attr_reader :dependency
|
571
|
-
sig { returns(T::Array[Dependabot::Credential]) }
|
572
|
-
attr_reader :credentials
|
573
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
574
|
-
attr_reader :dependency_files
|
575
|
-
sig { returns(T::Array[String]) }
|
576
|
-
attr_reader :ignored_versions
|
577
|
-
sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
|
578
|
-
attr_reader :security_advisories
|
579
|
-
|
580
|
-
sig { returns(T::Boolean) }
|
581
|
-
def valid_npm_details?
|
582
|
-
!npm_details&.fetch("dist-tags", nil).nil?
|
583
|
-
end
|
584
|
-
|
585
|
-
sig { params(versions_array: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
|
586
|
-
def filter_ignored_versions(versions_array)
|
587
|
-
filtered = versions_array.reject do |v, _|
|
588
|
-
ignore_requirements.any? { |r| r.satisfied_by?(v) }
|
589
|
-
end
|
590
|
-
|
591
|
-
if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(versions_array).any?
|
592
|
-
raise AllVersionsIgnored
|
593
|
-
end
|
594
|
-
|
595
|
-
if versions_array.count > filtered.count
|
596
|
-
diff = versions_array.count - filtered.count
|
597
|
-
Dependabot.logger.info("Filtered out #{diff} ignored versions")
|
598
|
-
end
|
599
|
-
|
600
|
-
filtered
|
402
|
+
params(releases: T::Array[Dependabot::Package::PackageRelease])
|
403
|
+
.returns(T::Array[Dependabot::Package::PackageRelease])
|
601
404
|
end
|
602
|
-
|
603
|
-
sig { params(versions_array: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
|
604
|
-
def filter_out_of_range_versions(versions_array)
|
405
|
+
def filter_out_of_range_versions(releases)
|
605
406
|
reqs = dependency.requirements.filter_map do |r|
|
606
407
|
Bun::Requirement.requirements_array(r.fetch(:requirement))
|
607
408
|
end
|
608
409
|
|
609
|
-
|
610
|
-
|
611
|
-
end
|
612
|
-
|
613
|
-
sig { params(versions_array: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
|
614
|
-
def filter_lower_versions(versions_array)
|
615
|
-
return versions_array unless dependency.numeric_version
|
616
|
-
|
617
|
-
versions_array
|
618
|
-
.select { |version, _| version > dependency.numeric_version }
|
619
|
-
end
|
620
|
-
|
621
|
-
sig { returns(T.nilable(Version)) }
|
622
|
-
def version_from_dist_tags
|
623
|
-
details = npm_details
|
624
|
-
|
625
|
-
return nil unless details
|
626
|
-
|
627
|
-
dist_tags = details["dist-tags"].keys
|
628
|
-
|
629
|
-
# Check if a dist tag was specified as a requirement. If it was, and
|
630
|
-
# it exists, use it.
|
631
|
-
dist_tag_req = dependency.requirements
|
632
|
-
.find { |r| dist_tags.include?(r[:requirement]) }
|
633
|
-
&.fetch(:requirement)
|
634
|
-
|
635
|
-
if dist_tag_req
|
636
|
-
tag_vers =
|
637
|
-
version_class.new(details["dist-tags"][dist_tag_req])
|
638
|
-
return tag_vers unless yanked?(tag_vers)
|
410
|
+
releases.select do |release|
|
411
|
+
reqs.all? { |r| r.any? { |o| o.satisfied_by?(release.version) } }
|
639
412
|
end
|
640
|
-
|
641
|
-
# Use the latest dist tag unless there's a reason not to
|
642
|
-
return nil unless details["dist-tags"]["latest"]
|
643
|
-
|
644
|
-
latest = version_class.new(details["dist-tags"]["latest"])
|
645
|
-
|
646
|
-
wants_latest_dist_tag?(latest) ? latest : nil
|
647
|
-
end
|
648
|
-
|
649
|
-
sig { params(version: Version).returns(T::Boolean) }
|
650
|
-
def related_to_current_pre?(version)
|
651
|
-
current_version = dependency.numeric_version
|
652
|
-
if current_version&.prerelease? &&
|
653
|
-
current_version.release == version.release
|
654
|
-
return true
|
655
|
-
end
|
656
|
-
|
657
|
-
dependency.requirements.any? do |req|
|
658
|
-
next unless req[:requirement]&.match?(/\d-[A-Za-z]/)
|
659
|
-
|
660
|
-
Bun::Requirement
|
661
|
-
.requirements_array(req.fetch(:requirement))
|
662
|
-
.any? do |r|
|
663
|
-
r.requirements.any? { |a| a.last.release == version.release }
|
664
|
-
end
|
665
|
-
rescue Gem::Requirement::BadRequirementError
|
666
|
-
false
|
667
|
-
end
|
668
|
-
end
|
669
|
-
|
670
|
-
sig { returns(T::Boolean) }
|
671
|
-
def specified_dist_tag_requirement?
|
672
|
-
dependency.requirements.any? do |req|
|
673
|
-
next false if req[:requirement].nil?
|
674
|
-
next false unless req[:requirement].match?(/^[A-Za-z]/)
|
675
|
-
|
676
|
-
!req[:requirement].match?(/^v\d/i)
|
677
|
-
end
|
678
|
-
end
|
679
|
-
|
680
|
-
sig { params(latest_version: Version).returns(T::Boolean) }
|
681
|
-
def wants_latest_dist_tag?(latest_version)
|
682
|
-
ver = latest_version
|
683
|
-
return false if related_to_current_pre?(ver) ^ ver.prerelease?
|
684
|
-
return false if current_version_greater_than?(ver)
|
685
|
-
return false if current_requirement_greater_than?(ver)
|
686
|
-
return false if ignore_requirements.any? { |r| r.satisfied_by?(ver) }
|
687
|
-
return false if yanked?(ver)
|
688
|
-
|
689
|
-
true
|
690
|
-
end
|
691
|
-
|
692
|
-
sig { params(version: Version).returns(T::Boolean) }
|
693
|
-
def current_version_greater_than?(version)
|
694
|
-
return false unless dependency.numeric_version
|
695
|
-
|
696
|
-
T.must(dependency.numeric_version) > version
|
697
|
-
end
|
698
|
-
|
699
|
-
sig { params(version: Version).returns(T::Boolean) }
|
700
|
-
def current_requirement_greater_than?(version)
|
701
|
-
dependency.requirements.any? do |req|
|
702
|
-
next false unless req[:requirement]
|
703
|
-
|
704
|
-
req_version = req[:requirement].sub(/^\^|~|>=?/, "")
|
705
|
-
next false unless version_class.correct?(req_version)
|
706
|
-
|
707
|
-
version_class.new(req_version) > version
|
708
|
-
end
|
709
|
-
end
|
710
|
-
|
711
|
-
sig { params(version: Version).returns(T::Boolean) }
|
712
|
-
def yanked?(version)
|
713
|
-
return @yanked[version] || false if @yanked.key?(version)
|
714
|
-
|
715
|
-
@yanked[version] =
|
716
|
-
begin
|
717
|
-
if dependency_registry == "registry.npmjs.org"
|
718
|
-
status = Dependabot::RegistryClient.head(
|
719
|
-
url: registry_finder.tarball_url(version),
|
720
|
-
headers: registry_auth_headers
|
721
|
-
).status
|
722
|
-
else
|
723
|
-
status = Dependabot::RegistryClient.get(
|
724
|
-
url: dependency_url + "/#{version}",
|
725
|
-
headers: registry_auth_headers
|
726
|
-
).status
|
727
|
-
|
728
|
-
if status == 404
|
729
|
-
# Some registries don't handle escaped package names properly
|
730
|
-
status = Dependabot::RegistryClient.get(
|
731
|
-
url: dependency_url.gsub("%2F", "/") + "/#{version}",
|
732
|
-
headers: registry_auth_headers
|
733
|
-
).status
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
|
-
version_not_found = status == 404
|
738
|
-
version_not_found && version_endpoint_working?
|
739
|
-
rescue Excon::Error::Timeout, Excon::Error::Socket
|
740
|
-
# Give the benefit of the doubt if the registry is playing up
|
741
|
-
false
|
742
|
-
end
|
743
|
-
|
744
|
-
@yanked[version] || false
|
745
|
-
end
|
746
|
-
|
747
|
-
sig { returns(T.nilable(T::Boolean)) }
|
748
|
-
def version_endpoint_working?
|
749
|
-
return true if dependency_registry == "registry.npmjs.org"
|
750
|
-
|
751
|
-
return @version_endpoint_working if @version_endpoint_working
|
752
|
-
|
753
|
-
@version_endpoint_working =
|
754
|
-
begin
|
755
|
-
Dependabot::RegistryClient.get(
|
756
|
-
url: dependency_url + "/latest",
|
757
|
-
headers: registry_auth_headers
|
758
|
-
).status < 400
|
759
|
-
rescue Excon::Error::Timeout, Excon::Error::Socket
|
760
|
-
# Give the benefit of the doubt if the registry is playing up
|
761
|
-
true
|
762
|
-
end
|
763
|
-
@version_endpoint_working
|
764
|
-
end
|
765
|
-
|
766
|
-
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
767
|
-
def npm_details
|
768
|
-
return @npm_details if @npm_details
|
769
|
-
|
770
|
-
@npm_details = fetch_npm_details
|
771
|
-
end
|
772
|
-
|
773
|
-
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
774
|
-
def fetch_npm_details
|
775
|
-
npm_response = fetch_npm_response
|
776
|
-
|
777
|
-
return nil unless npm_response
|
778
|
-
|
779
|
-
check_npm_response(npm_response)
|
780
|
-
JSON.parse(npm_response.body)
|
781
|
-
rescue JSON::ParserError,
|
782
|
-
Excon::Error::Timeout,
|
783
|
-
Excon::Error::Socket,
|
784
|
-
RegistryError => e
|
785
|
-
if git_dependency?
|
786
|
-
nil
|
787
|
-
else
|
788
|
-
raise_npm_details_error(e)
|
789
|
-
end
|
790
|
-
end
|
791
|
-
|
792
|
-
sig { returns(T.nilable(Excon::Response)) }
|
793
|
-
def fetch_npm_response
|
794
|
-
response = Dependabot::RegistryClient.get(
|
795
|
-
url: dependency_url,
|
796
|
-
headers: registry_auth_headers
|
797
|
-
)
|
798
|
-
return response unless response.status == 500
|
799
|
-
return response unless registry_auth_headers["Authorization"]
|
800
|
-
|
801
|
-
auth = registry_auth_headers["Authorization"]
|
802
|
-
return response unless auth&.start_with?("Basic")
|
803
|
-
|
804
|
-
decoded_token = Base64.decode64(auth.gsub("Basic ", ""))
|
805
|
-
return unless decoded_token.include?(":")
|
806
|
-
|
807
|
-
username, password = decoded_token.split(":")
|
808
|
-
Dependabot::RegistryClient.get(
|
809
|
-
url: dependency_url,
|
810
|
-
options: {
|
811
|
-
user: username,
|
812
|
-
password: password
|
813
|
-
}
|
814
|
-
)
|
815
|
-
rescue URI::InvalidURIError => e
|
816
|
-
raise DependencyFileNotResolvable, e.message
|
817
|
-
end
|
818
|
-
|
819
|
-
sig { params(npm_response: Excon::Response).void }
|
820
|
-
def check_npm_response(npm_response)
|
821
|
-
return if git_dependency?
|
822
|
-
|
823
|
-
if private_dependency_not_reachable?(npm_response)
|
824
|
-
raise PrivateSourceAuthenticationFailure, dependency_registry
|
825
|
-
end
|
826
|
-
|
827
|
-
# handles scenario when private registry returns a server error 5xx
|
828
|
-
if private_dependency_server_error?(npm_response)
|
829
|
-
msg = "Server error #{npm_response.status} returned while accessing registry" \
|
830
|
-
" #{dependency_registry}."
|
831
|
-
raise DependencyFileNotResolvable, msg
|
832
|
-
end
|
833
|
-
|
834
|
-
status = npm_response.status
|
835
|
-
|
836
|
-
# handles issue when status 200 is returned from registry but with an invalid JSON object
|
837
|
-
if status.to_s.start_with?("2") && response_invalid_json?(npm_response)
|
838
|
-
msg = "Invalid JSON object returned from registry #{dependency_registry}."
|
839
|
-
Dependabot.logger.warn("#{msg} Response body (truncated) : #{npm_response.body[0..500]}...")
|
840
|
-
raise DependencyFileNotResolvable, msg
|
841
|
-
end
|
842
|
-
|
843
|
-
return if status.to_s.start_with?("2")
|
844
|
-
|
845
|
-
# Ignore 404s from the registry for updates where a lockfile doesn't
|
846
|
-
# need to be generated. The 404 won't cause problems later.
|
847
|
-
return if status == 404 && dependency.version.nil?
|
848
|
-
|
849
|
-
msg = "Got #{status} response with body #{npm_response.body}"
|
850
|
-
raise RegistryError.new(status, msg)
|
851
|
-
end
|
852
|
-
|
853
|
-
sig { params(error: Exception).void }
|
854
|
-
def raise_npm_details_error(error)
|
855
|
-
raise if dependency_registry == "registry.npmjs.org"
|
856
|
-
raise unless error.is_a?(Excon::Error::Timeout)
|
857
|
-
|
858
|
-
raise PrivateSourceTimedOut, dependency_registry
|
859
|
-
end
|
860
|
-
|
861
|
-
sig { params(npm_response: Excon::Response).returns(T::Boolean) }
|
862
|
-
def private_dependency_not_reachable?(npm_response)
|
863
|
-
return true if npm_response.body.start_with?(/user ".*?" is not a /)
|
864
|
-
return false unless [401, 402, 403, 404].include?(npm_response.status)
|
865
|
-
|
866
|
-
# Check whether this dependency is (likely to be) private
|
867
|
-
if dependency_registry == "registry.npmjs.org"
|
868
|
-
return false unless dependency.name.start_with?("@")
|
869
|
-
|
870
|
-
web_response = Dependabot::RegistryClient.get(url: "https://www.npmjs.com/package/#{dependency.name}")
|
871
|
-
# NOTE: returns 429 when the login page is rate limited
|
872
|
-
return web_response.body.include?("Forgot password?") ||
|
873
|
-
web_response.status == 429
|
874
|
-
end
|
875
|
-
|
876
|
-
true
|
877
|
-
end
|
878
|
-
|
879
|
-
sig { params(npm_response: Excon::Response).returns(T::Boolean) }
|
880
|
-
def private_dependency_server_error?(npm_response)
|
881
|
-
if [500, 501, 502, 503].include?(npm_response.status)
|
882
|
-
Dependabot.logger.warn("#{dependency_registry} returned code #{npm_response.status} with " \
|
883
|
-
"body #{npm_response.body}.")
|
884
|
-
return true
|
885
|
-
end
|
886
|
-
false
|
887
|
-
end
|
888
|
-
|
889
|
-
sig { params(npm_response: Excon::Response).returns(T::Boolean) }
|
890
|
-
def response_invalid_json?(npm_response)
|
891
|
-
result = JSON.parse(npm_response.body)
|
892
|
-
result.is_a?(Hash) || result.is_a?(Array)
|
893
|
-
false
|
894
|
-
rescue JSON::ParserError, TypeError
|
895
|
-
true
|
896
|
-
end
|
897
|
-
|
898
|
-
sig { returns(String) }
|
899
|
-
def dependency_url
|
900
|
-
registry_finder.dependency_url
|
901
|
-
end
|
902
|
-
|
903
|
-
sig { returns(String) }
|
904
|
-
def dependency_registry
|
905
|
-
registry_finder.registry
|
906
|
-
end
|
907
|
-
|
908
|
-
sig { returns(T::Hash[String, String]) }
|
909
|
-
def registry_auth_headers
|
910
|
-
registry_finder.auth_headers
|
911
|
-
end
|
912
|
-
|
913
|
-
sig { returns(Package::RegistryFinder) }
|
914
|
-
def registry_finder
|
915
|
-
return @registry_finder if @registry_finder
|
916
|
-
|
917
|
-
@registry_finder = Package::RegistryFinder.new(
|
918
|
-
dependency: dependency,
|
919
|
-
credentials: credentials,
|
920
|
-
npmrc_file: npmrc_file
|
921
|
-
)
|
922
|
-
@registry_finder
|
923
|
-
end
|
924
|
-
|
925
|
-
sig { returns(T::Array[Dependabot::Requirement]) }
|
926
|
-
def ignore_requirements
|
927
|
-
ignored_versions.flat_map { |req| requirement_class.requirements_array(req) }
|
928
|
-
end
|
929
|
-
|
930
|
-
sig { returns(T.class_of(Version)) }
|
931
|
-
def version_class
|
932
|
-
Dependabot::Bun::Version
|
933
|
-
end
|
934
|
-
|
935
|
-
sig { returns(T.class_of(Requirement)) }
|
936
|
-
def requirement_class
|
937
|
-
Dependabot::Bun::Requirement
|
938
|
-
end
|
939
|
-
|
940
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
941
|
-
def npmrc_file
|
942
|
-
dependency_files.find { |f| f.name.end_with?(".npmrc") }
|
943
|
-
end
|
944
|
-
|
945
|
-
sig { returns(T::Boolean) }
|
946
|
-
def git_dependency?
|
947
|
-
# ignored_version/raise_on_ignored are irrelevant.
|
948
|
-
GitCommitChecker.new(
|
949
|
-
dependency: dependency,
|
950
|
-
credentials: credentials
|
951
|
-
).git_dependency?
|
952
413
|
end
|
953
414
|
end
|
954
415
|
end
|
@@ -60,7 +60,7 @@ module Dependabot
|
|
60
60
|
dependency_files: T::Array[Dependabot::DependencyFile],
|
61
61
|
credentials: T::Array[Dependabot::Credential],
|
62
62
|
latest_allowable_version: T.nilable(T.any(String, Gem::Version)),
|
63
|
-
latest_version_finder:
|
63
|
+
latest_version_finder: PackageLatestVersionFinder,
|
64
64
|
repo_contents_path: T.nilable(String),
|
65
65
|
dependency_group: T.nilable(Dependabot::DependencyGroup),
|
66
66
|
raise_on_ignored: T::Boolean,
|
@@ -79,11 +79,7 @@ module Dependabot
|
|
79
79
|
@latest_allowable_version = latest_allowable_version
|
80
80
|
@dependency_group = dependency_group
|
81
81
|
|
82
|
-
@latest_version_finder = T.let(
|
83
|
-
{},
|
84
|
-
T::Hash[Dependabot::Dependency, T.any(LatestVersionFinder, PackageLatestVersionFinder)
|
85
|
-
]
|
86
|
-
)
|
82
|
+
@latest_version_finder = T.let({}, T::Hash[Dependabot::Dependency, PackageLatestVersionFinder])
|
87
83
|
@latest_version_finder[dependency] = latest_version_finder
|
88
84
|
@repo_contents_path = repo_contents_path
|
89
85
|
@raise_on_ignored = raise_on_ignored
|
@@ -189,34 +185,18 @@ module Dependabot
|
|
189
185
|
sig { returns(T::Boolean) }
|
190
186
|
attr_reader :raise_on_ignored
|
191
187
|
|
192
|
-
sig { params(dep: Dependabot::Dependency) .returns(
|
188
|
+
sig { params(dep: Dependabot::Dependency) .returns(PackageLatestVersionFinder) }
|
193
189
|
def latest_version_finder(dep)
|
194
190
|
@latest_version_finder[dep] ||=
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
)
|
205
|
-
else
|
206
|
-
LatestVersionFinder.new(
|
207
|
-
dependency: dep,
|
208
|
-
credentials: credentials,
|
209
|
-
dependency_files: dependency_files,
|
210
|
-
ignored_versions: [],
|
211
|
-
security_advisories: [],
|
212
|
-
raise_on_ignored: raise_on_ignored
|
213
|
-
)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
sig { returns(T::Boolean) }
|
218
|
-
def enable_cooldown?
|
219
|
-
Dependabot::Experiments.enabled?(:enable_cooldown_for_npm_and_yarn)
|
191
|
+
PackageLatestVersionFinder.new(
|
192
|
+
dependency: dep,
|
193
|
+
dependency_files: dependency_files,
|
194
|
+
credentials: credentials,
|
195
|
+
cooldown_options: update_cooldown,
|
196
|
+
ignored_versions: [],
|
197
|
+
security_advisories: [],
|
198
|
+
raise_on_ignored: raise_on_ignored
|
199
|
+
)
|
220
200
|
end
|
221
201
|
|
222
202
|
# rubocop:disable Metrics/PerceivedComplexity
|
@@ -533,7 +513,11 @@ module Dependabot
|
|
533
513
|
rescue Gem::Requirement::BadRequirementError
|
534
514
|
false
|
535
515
|
end
|
536
|
-
end.map
|
516
|
+
end.map do |versions_with_details| # rubocop:disable Style/MultilineBlockChain
|
517
|
+
# Return just the version
|
518
|
+
version, = versions_with_details
|
519
|
+
version
|
520
|
+
end
|
537
521
|
end
|
538
522
|
|
539
523
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -41,7 +41,7 @@ module Dependabot
|
|
41
41
|
requirements_update_strategy: nil, dependency_group: nil,
|
42
42
|
update_cooldown: nil, options: {})
|
43
43
|
@latest_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
|
44
|
-
@latest_resolvable_version = T.let(nil, T.nilable(T.any(String,
|
44
|
+
@latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
|
45
45
|
@updated_requirements = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
|
46
46
|
@vulnerability_audit = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
|
47
47
|
@vulnerable_versions = T.let(nil, T.nilable(T::Array[T.any(String, Gem::Version)]))
|
@@ -49,9 +49,7 @@ module Dependabot
|
|
49
49
|
@latest_version_for_git_dependency = T.let(nil, T.nilable(T.any(String, Gem::Version)))
|
50
50
|
@latest_released_version = T.let(nil, T.nilable(Gem::Version))
|
51
51
|
@latest_version_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
52
|
-
@latest_version_finder = T.let(
|
53
|
-
nil, T.nilable(T.any(LatestVersionFinder, PackageLatestVersionFinder))
|
54
|
-
)
|
52
|
+
@latest_version_finder = T.let(nil, T.nilable(PackageLatestVersionFinder))
|
55
53
|
@version_resolver = T.let(nil, T.nilable(VersionResolver))
|
56
54
|
@subdependency_version_resolver = T.let(nil, T.nilable(SubdependencyVersionResolver))
|
57
55
|
@library = T.let(nil, T.nilable(T::Boolean))
|
@@ -86,17 +84,23 @@ module Dependabot
|
|
86
84
|
end
|
87
85
|
end
|
88
86
|
|
89
|
-
sig { override.returns(T.nilable(T.any(String,
|
87
|
+
sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
|
90
88
|
def latest_resolvable_version
|
91
89
|
return unless latest_version
|
92
90
|
|
93
91
|
@latest_resolvable_version ||=
|
94
92
|
if dependency.top_level?
|
95
|
-
|
93
|
+
T.cast(
|
94
|
+
version_resolver.latest_resolvable_version,
|
95
|
+
T.nilable(T.any(String, Dependabot::Version))
|
96
|
+
)
|
96
97
|
else
|
97
98
|
# If the dependency is indirect its version is constrained by the
|
98
99
|
# requirements placed on it by dependencies lower down the tree
|
99
|
-
|
100
|
+
T.cast(
|
101
|
+
subdependency_version_resolver.latest_resolvable_version,
|
102
|
+
T.nilable(T.any(String, Dependabot::Version))
|
103
|
+
)
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
@@ -131,7 +135,9 @@ module Dependabot
|
|
131
135
|
|
132
136
|
sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
|
133
137
|
def latest_resolvable_version_with_no_unlock
|
134
|
-
|
138
|
+
unless dependency.top_level?
|
139
|
+
return T.cast(latest_resolvable_version, T.nilable(T.any(String, Dependabot::Version)))
|
140
|
+
end
|
135
141
|
|
136
142
|
return latest_resolvable_version_with_no_unlock_for_git_dependency if git_dependency?
|
137
143
|
|
@@ -165,7 +171,7 @@ module Dependabot
|
|
165
171
|
requirements: dependency.requirements,
|
166
172
|
updated_source: updated_source,
|
167
173
|
latest_resolvable_version: resolvable_version,
|
168
|
-
update_strategy: requirements_update_strategy
|
174
|
+
update_strategy: T.must(requirements_update_strategy)
|
169
175
|
).updated_requirements
|
170
176
|
end
|
171
177
|
|
@@ -324,7 +330,7 @@ module Dependabot
|
|
324
330
|
requirements: original_dep.requirements,
|
325
331
|
updated_source: original_dep == dependency ? updated_source : original_source(original_dep),
|
326
332
|
latest_resolvable_version: version,
|
327
|
-
update_strategy: requirements_update_strategy
|
333
|
+
update_strategy: T.must(requirements_update_strategy)
|
328
334
|
).updated_requirements,
|
329
335
|
previous_version: previous_version,
|
330
336
|
previous_requirements: original_dep.requirements,
|
@@ -401,34 +407,17 @@ module Dependabot
|
|
401
407
|
end
|
402
408
|
end
|
403
409
|
|
404
|
-
sig { returns(
|
410
|
+
sig { returns(PackageLatestVersionFinder) }
|
405
411
|
def latest_version_finder
|
406
|
-
@latest_version_finder ||=
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
cooldown_options: @update_cooldown
|
416
|
-
)
|
417
|
-
else
|
418
|
-
LatestVersionFinder.new(
|
419
|
-
dependency: dependency,
|
420
|
-
credentials: credentials,
|
421
|
-
dependency_files: dependency_files,
|
422
|
-
ignored_versions: ignored_versions,
|
423
|
-
raise_on_ignored: raise_on_ignored,
|
424
|
-
security_advisories: security_advisories
|
425
|
-
)
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
sig { returns(T::Boolean) }
|
430
|
-
def enable_cooldown?
|
431
|
-
Dependabot::Experiments.enabled?(:enable_cooldown_for_bun)
|
412
|
+
@latest_version_finder ||= PackageLatestVersionFinder.new(
|
413
|
+
dependency: dependency,
|
414
|
+
credentials: credentials,
|
415
|
+
dependency_files: dependency_files,
|
416
|
+
ignored_versions: ignored_versions,
|
417
|
+
raise_on_ignored: raise_on_ignored,
|
418
|
+
security_advisories: security_advisories,
|
419
|
+
cooldown_options: @update_cooldown
|
420
|
+
)
|
432
421
|
end
|
433
422
|
|
434
423
|
sig { returns(VersionResolver) }
|
@@ -514,7 +503,7 @@ module Dependabot
|
|
514
503
|
|
515
504
|
@library =
|
516
505
|
LibraryDetector.new(
|
517
|
-
package_json_file: package_json,
|
506
|
+
package_json_file: T.must(package_json),
|
518
507
|
credentials: credentials,
|
519
508
|
dependency_files: dependency_files
|
520
509
|
).library?
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-bun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.322.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.
|
18
|
+
version: 0.322.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.
|
25
|
+
version: 0.322.0
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: debug
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -347,7 +347,7 @@ licenses:
|
|
347
347
|
- MIT
|
348
348
|
metadata:
|
349
349
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
350
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
350
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.322.0
|
351
351
|
rdoc_options: []
|
352
352
|
require_paths:
|
353
353
|
- lib
|