dependabot-common 0.395.0 → 0.396.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 +4 -4
- data/lib/dependabot/package/cooldown_date_tracker.rb +168 -0
- data/lib/dependabot/package/npm_lockfile_details.rb +37 -0
- data/lib/dependabot/package/npm_package_json.rb +83 -0
- data/lib/dependabot/package/package_latest_version_finder.rb +68 -47
- data/lib/dependabot/update_checkers/cooldown_calculation.rb +21 -0
- data/lib/dependabot.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 38e1442399b4db684997304709cfd914195b3a067d6195989cebead9c1c5d188
|
|
4
|
+
data.tar.gz: 5a949d0992ee5bddd0ce5f0641ddcc9fe7e70ca32ce21dafbd7504e07e293069
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7fcf1078fd4be3cfbd95be9b1529f6ee5c159f0891ad0baebbd42931a21fd2f2b6c02172614c6c537f72115d414aee3feede98296ae5a52c65fe6abafcd9dd82
|
|
7
|
+
data.tar.gz: 5304d03eb4968bd94732bee2f81e02405e1714c14258aae73735d68f07705c4a80f2c7c7ff96cfc2b65bc1814fbd01aa44b75fbe9cd5e7450304bcee3e3d5fb0
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/dependency"
|
|
7
|
+
require "dependabot/package/package_release"
|
|
8
|
+
require "dependabot/update_checkers/cooldown_calculation"
|
|
9
|
+
|
|
10
|
+
module Dependabot
|
|
11
|
+
module Package
|
|
12
|
+
class CooldownDateTracker
|
|
13
|
+
extend T::Sig
|
|
14
|
+
|
|
15
|
+
sig { params(dependency: Dependabot::Dependency, ignored_versions: T::Array[String]).void }
|
|
16
|
+
def initialize(dependency:, ignored_versions:)
|
|
17
|
+
@dependency = dependency
|
|
18
|
+
@ignored_versions = ignored_versions
|
|
19
|
+
@active = T.let(false, T::Boolean)
|
|
20
|
+
@language_version = T.let(nil, T.nilable(T.any(String, Dependabot::Version)))
|
|
21
|
+
@enforce_requirements = T.let(false, T::Boolean)
|
|
22
|
+
@prefiltered = T.let(false, T::Boolean)
|
|
23
|
+
@releases = T.let({}, T::Hash[Dependabot::Package::PackageRelease, Integer])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
sig { returns(T::Boolean) }
|
|
27
|
+
attr_reader :active
|
|
28
|
+
|
|
29
|
+
sig do
|
|
30
|
+
params(
|
|
31
|
+
language_version: T.nilable(T.any(String, Dependabot::Version)),
|
|
32
|
+
requirements: T::Boolean,
|
|
33
|
+
block: T.proc.returns(T::Array[Dependabot::Package::PackageRelease])
|
|
34
|
+
).returns(T::Array[Dependabot::Package::PackageRelease])
|
|
35
|
+
end
|
|
36
|
+
def filter(language_version:, requirements:, &block)
|
|
37
|
+
@active = true
|
|
38
|
+
@language_version = language_version
|
|
39
|
+
@enforce_requirements = requirements
|
|
40
|
+
|
|
41
|
+
filtered = yield
|
|
42
|
+
mark_for_selected_release(filtered)
|
|
43
|
+
filtered
|
|
44
|
+
ensure
|
|
45
|
+
@active = false
|
|
46
|
+
@language_version = nil
|
|
47
|
+
@enforce_requirements = false
|
|
48
|
+
@releases.clear
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
sig do
|
|
52
|
+
params(block: T.proc.returns(T::Array[Dependabot::Package::PackageRelease]))
|
|
53
|
+
.returns(T::Array[Dependabot::Package::PackageRelease])
|
|
54
|
+
end
|
|
55
|
+
def filter_prefiltered(&block)
|
|
56
|
+
@prefiltered = true
|
|
57
|
+
filter(language_version: nil, requirements: false, &block)
|
|
58
|
+
ensure
|
|
59
|
+
@prefiltered = false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
sig do
|
|
63
|
+
params(
|
|
64
|
+
release: Dependabot::Package::PackageRelease,
|
|
65
|
+
current_version: T.nilable(Dependabot::Version),
|
|
66
|
+
days: Integer
|
|
67
|
+
).void
|
|
68
|
+
end
|
|
69
|
+
def record(release:, current_version:, days:)
|
|
70
|
+
return unless active
|
|
71
|
+
return unless @prefiltered || relevant?(release, current_version)
|
|
72
|
+
|
|
73
|
+
@releases[release] = days
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
sig { returns(Dependabot::Dependency) }
|
|
79
|
+
attr_reader :dependency
|
|
80
|
+
|
|
81
|
+
sig { returns(T::Array[String]) }
|
|
82
|
+
attr_reader :ignored_versions
|
|
83
|
+
|
|
84
|
+
sig do
|
|
85
|
+
params(
|
|
86
|
+
release: Dependabot::Package::PackageRelease,
|
|
87
|
+
current_version: T.nilable(Dependabot::Version)
|
|
88
|
+
).returns(T::Boolean)
|
|
89
|
+
end
|
|
90
|
+
def relevant?(release, current_version)
|
|
91
|
+
return false if release.yanked?
|
|
92
|
+
return false if current_version && release.version <= current_version
|
|
93
|
+
return false if unwanted_prerelease?(release)
|
|
94
|
+
return false if ignored?(release)
|
|
95
|
+
return false unless language_supported?(release)
|
|
96
|
+
|
|
97
|
+
requirements_allow?(release)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
101
|
+
def unwanted_prerelease?(release)
|
|
102
|
+
release.version.prerelease? && !wants_prerelease?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
sig { returns(T::Boolean) }
|
|
106
|
+
def wants_prerelease?
|
|
107
|
+
return true if dependency.numeric_version&.prerelease?
|
|
108
|
+
|
|
109
|
+
dependency.requirements.any? do |requirement|
|
|
110
|
+
requirement_string = requirement.requirement_string || ""
|
|
111
|
+
requirement_string.split(",").map(&:strip).any? do |part|
|
|
112
|
+
version_string = part.gsub(/^\s*[!<>=~^]+\s*/, "").strip
|
|
113
|
+
next false unless dependency.version_class.correct?(version_string)
|
|
114
|
+
|
|
115
|
+
dependency.version_class.new(version_string).prerelease?
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
121
|
+
def ignored?(release)
|
|
122
|
+
requirements = ignored_versions.flat_map do |requirement|
|
|
123
|
+
dependency.requirement_class.requirements_array(requirement)
|
|
124
|
+
end
|
|
125
|
+
requirements.any? { |requirement| requirement.satisfied_by?(release.version) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
129
|
+
def language_supported?(release)
|
|
130
|
+
requirement = release.language&.requirement
|
|
131
|
+
!@language_version || !requirement || requirement.satisfied_by?(@language_version)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
135
|
+
def requirements_allow?(release)
|
|
136
|
+
return true unless @enforce_requirements
|
|
137
|
+
|
|
138
|
+
dependency.requirements.filter_map(&:requirement_string).all? do |requirement_string|
|
|
139
|
+
dependency.requirement_class.requirements_array(requirement_string).any? do |requirement|
|
|
140
|
+
requirement.satisfied_by?(release.version)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
sig { params(filtered: T::Array[Dependabot::Package::PackageRelease]).void }
|
|
146
|
+
def mark_for_selected_release(filtered)
|
|
147
|
+
return if @releases.empty?
|
|
148
|
+
|
|
149
|
+
current_version = dependency.numeric_version
|
|
150
|
+
eligible = if @prefiltered
|
|
151
|
+
filtered
|
|
152
|
+
else
|
|
153
|
+
filtered.select { |release| relevant?(release, current_version) }
|
|
154
|
+
end
|
|
155
|
+
selected = (eligible + @releases.keys).max_by(&:version)
|
|
156
|
+
return unless selected
|
|
157
|
+
|
|
158
|
+
days = @releases[selected]
|
|
159
|
+
return unless days
|
|
160
|
+
|
|
161
|
+
Dependabot::UpdateCheckers::CooldownCalculation.mark_cooldown_date_unavailable(
|
|
162
|
+
dependency,
|
|
163
|
+
cooldown_days: days
|
|
164
|
+
)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
require "dependabot/errors"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
module Package
|
|
9
|
+
class NpmLockfileDetails < T::ImmutableStruct
|
|
10
|
+
extend T::Sig
|
|
11
|
+
|
|
12
|
+
const :version, T.nilable(String), default: nil
|
|
13
|
+
const :resolved, T.nilable(String), default: nil
|
|
14
|
+
const :resolution, T.nilable(String), default: nil
|
|
15
|
+
|
|
16
|
+
sig { params(value: Object, path: String, context: String).returns(NpmLockfileDetails) }
|
|
17
|
+
def self.from_object(value, path:, context:)
|
|
18
|
+
raise DependencyFileNotParseable.new(path, "#{context} must be an object") unless value.is_a?(Hash)
|
|
19
|
+
|
|
20
|
+
new(
|
|
21
|
+
version: optional_string(T.cast(value["version"], Object), path, "#{context}.version"),
|
|
22
|
+
resolved: optional_string(T.cast(value["resolved"], Object), path, "#{context}.resolved"),
|
|
23
|
+
resolution: optional_string(T.cast(value["resolution"], Object), path, "#{context}.resolution")
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sig { params(value: Object, path: String, field: String).returns(T.nilable(String)) }
|
|
28
|
+
def self.optional_string(value, path, field)
|
|
29
|
+
return if value.nil?
|
|
30
|
+
return value if value.is_a?(String)
|
|
31
|
+
|
|
32
|
+
raise DependencyFileNotParseable.new(path, "#{field} must be a string or nil")
|
|
33
|
+
end
|
|
34
|
+
private_class_method :optional_string
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
require "sorbet-runtime"
|
|
6
|
+
|
|
7
|
+
require "dependabot/dependency_file"
|
|
8
|
+
require "dependabot/package/npm_package_manager_config"
|
|
9
|
+
|
|
10
|
+
module Dependabot
|
|
11
|
+
module Package
|
|
12
|
+
class NpmPackageJson
|
|
13
|
+
extend T::Sig
|
|
14
|
+
|
|
15
|
+
ObjectHash = T.type_alias { T::Hash[String, Object] }
|
|
16
|
+
DEPENDENCY_TYPES = %w(dependencies devDependencies optionalDependencies).freeze
|
|
17
|
+
|
|
18
|
+
sig { params(file: DependencyFile).returns(NpmPackageJson) }
|
|
19
|
+
def self.from_file(file)
|
|
20
|
+
new(T.cast(JSON.parse(T.must(file.content)), Object), file.path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
sig { params(data: Object, path: String).void }
|
|
24
|
+
def initialize(data, path)
|
|
25
|
+
@path = path
|
|
26
|
+
@data = T.let(object_hash(data, "root"), ObjectHash)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
sig do
|
|
30
|
+
params(_block: T.proc.params(name: String, requirement: String, type: String).void).void
|
|
31
|
+
end
|
|
32
|
+
def each_dependency(&_block)
|
|
33
|
+
DEPENDENCY_TYPES.each do |type|
|
|
34
|
+
dependencies = @data[type]
|
|
35
|
+
next unless dependencies
|
|
36
|
+
|
|
37
|
+
object_hash(dependencies, type).each do |name, requirement|
|
|
38
|
+
next unless requirement.is_a?(String)
|
|
39
|
+
|
|
40
|
+
yield name, requirement, type
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
sig { returns(T.nilable(String)) }
|
|
46
|
+
def name
|
|
47
|
+
value = @data["name"]
|
|
48
|
+
value if value.is_a?(String)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
sig { returns(T::Boolean) }
|
|
52
|
+
def flat?
|
|
53
|
+
!!@data["flat"]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
sig { returns(T::Boolean) }
|
|
57
|
+
def workspaces?
|
|
58
|
+
!!@data["workspaces"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
sig { returns(NpmPackageManagerConfig) }
|
|
62
|
+
def package_manager_config
|
|
63
|
+
NpmPackageManagerConfig.from_package_json(@data)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
sig { params(value: Object, field: String).returns(ObjectHash) }
|
|
69
|
+
def object_hash(value, field)
|
|
70
|
+
raise TypeError, "#{@path}: #{field} must be an object" unless value.is_a?(Hash)
|
|
71
|
+
|
|
72
|
+
result = T.let({}, ObjectHash)
|
|
73
|
+
value.each do |raw_key, raw_value|
|
|
74
|
+
key = T.cast(raw_key, Object)
|
|
75
|
+
raise TypeError, "#{@path}: #{field} keys must be strings" unless key.is_a?(String)
|
|
76
|
+
|
|
77
|
+
result[key] = T.cast(raw_value, Object)
|
|
78
|
+
end
|
|
79
|
+
result
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -12,10 +12,11 @@ require "dependabot/update_checkers/cooldown_calculation"
|
|
|
12
12
|
require "dependabot/registry_client"
|
|
13
13
|
require "dependabot/package/package_details"
|
|
14
14
|
require "dependabot/package/release_cooldown_options"
|
|
15
|
+
require "dependabot/package/cooldown_date_tracker"
|
|
15
16
|
|
|
16
17
|
module Dependabot
|
|
17
18
|
module Package
|
|
18
|
-
class PackageLatestVersionFinder
|
|
19
|
+
class PackageLatestVersionFinder # rubocop:disable Metrics/ClassLength
|
|
19
20
|
extend T::Sig
|
|
20
21
|
extend T::Helpers
|
|
21
22
|
|
|
@@ -79,6 +80,8 @@ module Dependabot
|
|
|
79
80
|
@latest_version_with_no_unlock = T.let(nil, T.nilable(Dependabot::Version))
|
|
80
81
|
@lowest_security_fix_version = T.let(nil, T.nilable(Dependabot::Version))
|
|
81
82
|
@package_details = T.let(nil, T.nilable(Dependabot::Package::PackageDetails))
|
|
83
|
+
cooldown_tracker = CooldownDateTracker.new(dependency: dependency, ignored_versions: ignored_versions)
|
|
84
|
+
@cooldown_tracker = T.let(cooldown_tracker, CooldownDateTracker)
|
|
82
85
|
end
|
|
83
86
|
|
|
84
87
|
sig do
|
|
@@ -121,15 +124,16 @@ module Dependabot
|
|
|
121
124
|
@lowest_security_fix_version ||= fetch_lowest_security_fix_version(language_version: language_version)
|
|
122
125
|
end
|
|
123
126
|
|
|
124
|
-
sig
|
|
125
|
-
returns(T.nilable(T::Array[Dependabot::Package::PackageRelease]))
|
|
126
|
-
end
|
|
127
|
+
sig { returns(T.nilable(T::Array[Dependabot::Package::PackageRelease])) }
|
|
127
128
|
def available_versions
|
|
128
129
|
package_details&.releases
|
|
129
130
|
end
|
|
130
131
|
|
|
131
132
|
protected
|
|
132
133
|
|
|
134
|
+
sig { returns(CooldownDateTracker) }
|
|
135
|
+
attr_reader :cooldown_tracker
|
|
136
|
+
|
|
133
137
|
sig do
|
|
134
138
|
params(language_version: T.nilable(T.any(String, Dependabot::Version)))
|
|
135
139
|
.returns(T.nilable(Dependabot::Version))
|
|
@@ -139,12 +143,13 @@ module Dependabot
|
|
|
139
143
|
return unless releases
|
|
140
144
|
|
|
141
145
|
releases = filter_yanked_versions(releases)
|
|
142
|
-
releases =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
releases = @cooldown_tracker.filter(language_version:, requirements: true) do
|
|
147
|
+
filtered = filter_by_cooldown(releases)
|
|
148
|
+
filtered = filter_prerelease_versions(filter_unsupported_versions(filtered, language_version))
|
|
149
|
+
filtered = filter_ignored_versions(filtered)
|
|
150
|
+
filtered = filter_out_of_range_versions(filtered)
|
|
151
|
+
apply_post_fetch_latest_versions_filter(filtered)
|
|
152
|
+
end
|
|
148
153
|
releases.max_by(&:version)&.version
|
|
149
154
|
end
|
|
150
155
|
|
|
@@ -154,9 +159,8 @@ module Dependabot
|
|
|
154
159
|
end
|
|
155
160
|
def filter_yanked_versions(releases)
|
|
156
161
|
filtered = releases.reject(&:yanked?)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
end
|
|
162
|
+
removed_count = releases.count - filtered.count
|
|
163
|
+
Dependabot.logger.info("Filtered out #{removed_count} yanked versions") if removed_count.positive?
|
|
160
164
|
filtered
|
|
161
165
|
end
|
|
162
166
|
|
|
@@ -165,8 +169,13 @@ module Dependabot
|
|
|
165
169
|
.returns(T::Array[Dependabot::Package::PackageRelease])
|
|
166
170
|
end
|
|
167
171
|
def filter_by_cooldown(releases)
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
unless @cooldown_tracker.active
|
|
173
|
+
return @cooldown_tracker.filter(language_version: nil, requirements: false) do
|
|
174
|
+
filter_by_cooldown(releases)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
return releases unless cooldown_enabled? && cooldown_options
|
|
170
179
|
|
|
171
180
|
filtered = releases.reject { |release| in_cooldown_period?(release) }
|
|
172
181
|
|
|
@@ -176,21 +185,11 @@ module Dependabot
|
|
|
176
185
|
|
|
177
186
|
# If all releases were filtered out due to cooldown and we have a current version, use it as fallback
|
|
178
187
|
if filtered.empty? && !releases.empty? && dependency.version
|
|
179
|
-
current_version_str = dependency.version
|
|
180
|
-
|
|
181
188
|
Dependabot.logger.info(
|
|
182
189
|
"All versions filtered by cooldown for #{dependency.name}, " \
|
|
183
|
-
"falling back to current version #{
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
# Create a PackageRelease for the current version
|
|
187
|
-
current_version = version_class.new(current_version_str)
|
|
188
|
-
current_release = Dependabot::Package::PackageRelease.new(
|
|
189
|
-
version: current_version,
|
|
190
|
-
released_at: nil,
|
|
191
|
-
tag: nil
|
|
190
|
+
"falling back to current version #{dependency.version}"
|
|
192
191
|
)
|
|
193
|
-
return [
|
|
192
|
+
return [cooldown_fallback_release]
|
|
194
193
|
end
|
|
195
194
|
|
|
196
195
|
filtered
|
|
@@ -198,20 +197,17 @@ module Dependabot
|
|
|
198
197
|
|
|
199
198
|
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
200
199
|
def in_cooldown_period?(release)
|
|
201
|
-
|
|
200
|
+
current_version = version_class.correct?(dependency.version) ? version_class.new(dependency.version) : nil
|
|
201
|
+
days = cooldown_days_for(current_version, release.version)
|
|
202
|
+
return false unless days.positive?
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
released_at = released_at_for(release)
|
|
205
|
+
unless released_at
|
|
206
|
+
@cooldown_tracker.record(release: release, current_version: current_version, days: days)
|
|
207
|
+
return missing_release_date_blocks_update?(release)
|
|
208
|
+
end
|
|
207
209
|
|
|
208
|
-
|
|
209
|
-
days = Dependabot::UpdateCheckers::CooldownCalculation.cooldown_days_for(
|
|
210
|
-
T.must(cooldown), current_version, release.version
|
|
211
|
-
)
|
|
212
|
-
Dependabot::UpdateCheckers::CooldownCalculation.within_cooldown_window?(
|
|
213
|
-
T.must(release.released_at), days
|
|
214
|
-
)
|
|
210
|
+
Dependabot::UpdateCheckers::CooldownCalculation.within_cooldown_window?(released_at, days)
|
|
215
211
|
end
|
|
216
212
|
|
|
217
213
|
sig do
|
|
@@ -223,10 +219,20 @@ module Dependabot
|
|
|
223
219
|
end
|
|
224
220
|
def filter_unsupported_versions(releases, language_version)
|
|
225
221
|
filtered = releases.filter_map do |release|
|
|
226
|
-
|
|
227
|
-
next release unless language_version
|
|
222
|
+
language = release.language
|
|
223
|
+
next release unless language_version && language
|
|
224
|
+
|
|
225
|
+
language_requirement = language.requirement
|
|
228
226
|
next release unless language_requirement
|
|
229
|
-
|
|
227
|
+
|
|
228
|
+
unless language_requirement.satisfied_by?(language_version)
|
|
229
|
+
Dependabot.logger.info(
|
|
230
|
+
"Filtered out #{dependency.name} #{release.version} because " \
|
|
231
|
+
"#{language.name} requirement #{language_requirement} is not satisfied by " \
|
|
232
|
+
"#{language.name} #{language_version}"
|
|
233
|
+
)
|
|
234
|
+
next
|
|
235
|
+
end
|
|
230
236
|
|
|
231
237
|
release
|
|
232
238
|
end
|
|
@@ -361,6 +367,20 @@ module Dependabot
|
|
|
361
367
|
true
|
|
362
368
|
end
|
|
363
369
|
|
|
370
|
+
# Registries that only expose a publication date through a second request resolve it here.
|
|
371
|
+
sig { overridable.params(release: Dependabot::Package::PackageRelease).returns(T.nilable(Time)) }
|
|
372
|
+
def released_at_for(release)
|
|
373
|
+
release.released_at
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
sig { overridable.params(_release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
|
|
377
|
+
def missing_release_date_blocks_update?(_release)
|
|
378
|
+
false
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
sig { overridable.returns(Dependabot::Package::PackageRelease) }
|
|
382
|
+
def cooldown_fallback_release = PackageRelease.new(version: version_class.new(T.must(dependency.version)))
|
|
383
|
+
|
|
364
384
|
sig do
|
|
365
385
|
params(language_version: T.nilable(T.any(String, Dependabot::Version)))
|
|
366
386
|
.returns(T.nilable(Dependabot::Version))
|
|
@@ -378,11 +398,12 @@ module Dependabot
|
|
|
378
398
|
return unless releases
|
|
379
399
|
|
|
380
400
|
releases = filter_yanked_versions(releases)
|
|
381
|
-
releases =
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
401
|
+
releases = @cooldown_tracker.filter(language_version:, requirements: false) do
|
|
402
|
+
filtered = filter_by_cooldown(releases)
|
|
403
|
+
filtered = filter_prerelease_versions(filter_unsupported_versions(filtered, language_version))
|
|
404
|
+
filtered = filter_ignored_versions(filtered)
|
|
405
|
+
apply_post_fetch_latest_versions_filter(filtered)
|
|
406
|
+
end
|
|
386
407
|
releases.max_by(&:version)
|
|
387
408
|
end
|
|
388
409
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
5
|
+
require "dependabot/dependency"
|
|
5
6
|
require "dependabot/package/release_cooldown_options"
|
|
6
7
|
require "dependabot/version"
|
|
7
8
|
|
|
@@ -16,6 +17,14 @@ module Dependabot
|
|
|
16
17
|
extend T::Sig
|
|
17
18
|
|
|
18
19
|
DAY_IN_SECONDS = T.let(24 * 60 * 60, Integer)
|
|
20
|
+
DATE_UNAVAILABLE_METADATA_KEY = :cooldown_date_unavailable
|
|
21
|
+
|
|
22
|
+
# Shared by the pull request notice and the job-level warning so both channels
|
|
23
|
+
# report the same diagnostic, whether or not the update produced a pull request.
|
|
24
|
+
DATE_UNAVAILABLE_NOTICE_TYPE = "cooldown_date_unavailable"
|
|
25
|
+
DATE_UNAVAILABLE_TITLE = "Cooldown was not applied"
|
|
26
|
+
DATE_UNAVAILABLE_DESCRIPTION =
|
|
27
|
+
"Cooldown could not be applied because no publication date was available from the registry."
|
|
19
28
|
|
|
20
29
|
sig { params(release_date: Time, cooldown_days: Integer).returns(T::Boolean) }
|
|
21
30
|
def self.within_cooldown_window?(release_date, cooldown_days)
|
|
@@ -50,6 +59,18 @@ module Dependabot
|
|
|
50
59
|
def self.skip_cooldown?(cooldown, dependency_name, cooldown_enabled: true)
|
|
51
60
|
cooldown.nil? || !cooldown_enabled || !cooldown.included?(dependency_name)
|
|
52
61
|
end
|
|
62
|
+
|
|
63
|
+
sig { params(dependency: Dependabot::Dependency, cooldown_days: Integer).void }
|
|
64
|
+
def self.mark_cooldown_date_unavailable(dependency, cooldown_days:)
|
|
65
|
+
return unless cooldown_days.positive?
|
|
66
|
+
|
|
67
|
+
dependency.metadata[DATE_UNAVAILABLE_METADATA_KEY] = true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
|
71
|
+
def self.cooldown_date_unavailable?(dependency)
|
|
72
|
+
dependency.metadata[DATE_UNAVAILABLE_METADATA_KEY] == true
|
|
73
|
+
end
|
|
53
74
|
end
|
|
54
75
|
end
|
|
55
76
|
end
|
data/lib/dependabot.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-common
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.396.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -572,6 +572,9 @@ files:
|
|
|
572
572
|
- lib/dependabot/metadata_finders/base/commits_finder.rb
|
|
573
573
|
- lib/dependabot/metadata_finders/base/release_finder.rb
|
|
574
574
|
- lib/dependabot/notices.rb
|
|
575
|
+
- lib/dependabot/package/cooldown_date_tracker.rb
|
|
576
|
+
- lib/dependabot/package/npm_lockfile_details.rb
|
|
577
|
+
- lib/dependabot/package/npm_package_json.rb
|
|
575
578
|
- lib/dependabot/package/npm_package_manager_config.rb
|
|
576
579
|
- lib/dependabot/package/npm_registry_package.rb
|
|
577
580
|
- lib/dependabot/package/package_details.rb
|
|
@@ -631,7 +634,7 @@ licenses:
|
|
|
631
634
|
- MIT
|
|
632
635
|
metadata:
|
|
633
636
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
634
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
637
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.396.0
|
|
635
638
|
rdoc_options: []
|
|
636
639
|
require_paths:
|
|
637
640
|
- lib
|