dependabot-common 0.394.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/clients/azure.rb +1 -2
- data/lib/dependabot/command_helpers.rb +3 -3
- data/lib/dependabot/errors.rb +1 -2
- data/lib/dependabot/file_fetchers/base.rb +1 -2
- data/lib/dependabot/file_updaters/artifact_updater.rb +1 -2
- data/lib/dependabot/git_commit_checker.rb +2 -2
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +1 -2
- 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/npm_registry_package.rb +10 -1
- data/lib/dependabot/package/package_latest_version_finder.rb +68 -47
- data/lib/dependabot/pull_request_creator/github.rb +1 -2
- data/lib/dependabot/pull_request_creator/labeler.rb +2 -4
- data/lib/dependabot/pull_request_creator/message_builder.rb +1 -2
- data/lib/dependabot/update_checkers/cooldown_calculation.rb +21 -0
- data/lib/dependabot.rb +1 -1
- metadata +10 -7
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
|
|
@@ -8,7 +8,7 @@ require "sorbet-runtime"
|
|
|
8
8
|
|
|
9
9
|
module Dependabot
|
|
10
10
|
module Clients
|
|
11
|
-
# rubocop:disable Metrics/ClassLength
|
|
11
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
12
12
|
class Azure
|
|
13
13
|
extend T::Sig
|
|
14
14
|
include JsonResponseParser
|
|
@@ -550,6 +550,5 @@ module Dependabot
|
|
|
550
550
|
sig { returns(Dependabot::Source) }
|
|
551
551
|
attr_reader :source
|
|
552
552
|
end
|
|
553
|
-
# rubocop:enable Metrics/ClassLength
|
|
554
553
|
end
|
|
555
554
|
end
|
|
@@ -11,7 +11,7 @@ module Dependabot
|
|
|
11
11
|
|
|
12
12
|
module TIMEOUTS
|
|
13
13
|
NO_TIME_OUT = -1 # No timeout
|
|
14
|
-
|
|
14
|
+
GRACEFULLY_STOP = 5 # 5 seconds for graceful termination
|
|
15
15
|
LOCAL = 30 # 30 seconds
|
|
16
16
|
NETWORK = 120 # 2 minutes
|
|
17
17
|
LONG_RUNNING = 300 # 5 minutes
|
|
@@ -185,8 +185,8 @@ module Dependabot
|
|
|
185
185
|
if observation&.dig(:gracefully_stop)
|
|
186
186
|
message = observation[:reason] || "Terminated by output_observer"
|
|
187
187
|
# If the observer indicates a graceful stop, terminate the process
|
|
188
|
-
# by adjusting the remaining timeout
|
|
189
|
-
timeout = [timeout, ((Time.now - last_output_time) +
|
|
188
|
+
# by adjusting the remaining timeout
|
|
189
|
+
timeout = [timeout, ((Time.now - last_output_time) + TIMEOUTS::GRACEFULLY_STOP).to_i].min
|
|
190
190
|
Dependabot.logger.warn("Terminating process due to observer signal: #{message}")
|
|
191
191
|
end
|
|
192
192
|
rescue EOFError
|
data/lib/dependabot/errors.rb
CHANGED
|
@@ -5,7 +5,7 @@ require "sorbet-runtime"
|
|
|
5
5
|
require "dependabot/error_details"
|
|
6
6
|
require "dependabot/utils"
|
|
7
7
|
|
|
8
|
-
# rubocop:disable Metrics/ModuleLength
|
|
8
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
9
9
|
module Dependabot
|
|
10
10
|
extend T::Sig
|
|
11
11
|
|
|
@@ -1010,4 +1010,3 @@ module Dependabot
|
|
|
1010
1010
|
end
|
|
1011
1011
|
end
|
|
1012
1012
|
end
|
|
1013
|
-
# rubocop:enable Metrics/ModuleLength
|
|
@@ -16,7 +16,7 @@ require "dependabot/clients/bitbucket_with_retries"
|
|
|
16
16
|
require "dependabot/clients/gitlab_with_retries"
|
|
17
17
|
require "dependabot/shared_helpers"
|
|
18
18
|
|
|
19
|
-
# rubocop:disable Metrics/ClassLength
|
|
19
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
20
20
|
module Dependabot
|
|
21
21
|
module FileFetchers
|
|
22
22
|
class RepositoryContent < T::ImmutableStruct
|
|
@@ -1030,4 +1030,3 @@ module Dependabot
|
|
|
1030
1030
|
end
|
|
1031
1031
|
end
|
|
1032
1032
|
end
|
|
1033
|
-
# rubocop:enable Metrics/ClassLength
|
|
@@ -36,9 +36,8 @@ module Dependabot
|
|
|
36
36
|
return [] unless repo_contents_path && target_directory
|
|
37
37
|
|
|
38
38
|
Dir.chdir(T.must(repo_contents_path)) do
|
|
39
|
-
# rubocop:disable Performance/DeletePrefix
|
|
39
|
+
# rubocop:disable-next Performance/DeletePrefix
|
|
40
40
|
relative_dir = Pathname.new(base_directory).sub(%r{\A/}, "").join(T.must(target_directory))
|
|
41
|
-
# rubocop:enable Performance/DeletePrefix
|
|
42
41
|
|
|
43
42
|
status = T.let(
|
|
44
43
|
SharedHelpers.run_shell_command(
|
|
@@ -23,7 +23,7 @@ require "dependabot/package/release_cooldown_options"
|
|
|
23
23
|
require "dependabot/update_checkers/cooldown_calculation"
|
|
24
24
|
require "dependabot/git_cooldown_date_resolver"
|
|
25
25
|
module Dependabot
|
|
26
|
-
# rubocop:disable Metrics/ClassLength
|
|
26
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
27
27
|
class GitCommitChecker
|
|
28
28
|
extend T::Sig
|
|
29
29
|
include Dependabot::GitCooldownDateResolver
|
|
@@ -265,6 +265,7 @@ module Dependabot
|
|
|
265
265
|
|
|
266
266
|
sig { returns(T.nilable(String)) }
|
|
267
267
|
def local_tag_for_pinned_sha
|
|
268
|
+
return @local_tag_for_pinned_sha if defined?(@local_tag_for_pinned_sha)
|
|
268
269
|
return unless pinned_ref_looks_like_commit_sha?
|
|
269
270
|
|
|
270
271
|
@local_tag_for_pinned_sha = T.let(
|
|
@@ -957,5 +958,4 @@ module Dependabot
|
|
|
957
958
|
SourceDetails.from_hash(details) if details
|
|
958
959
|
end
|
|
959
960
|
end
|
|
960
|
-
# rubocop:enable Metrics/ClassLength
|
|
961
961
|
end
|
|
@@ -24,7 +24,7 @@ module Dependabot
|
|
|
24
24
|
const :api_url, T.nilable(String), default: nil
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# rubocop:disable Metrics/ClassLength
|
|
27
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
28
28
|
class ChangelogFinder
|
|
29
29
|
extend T::Sig
|
|
30
30
|
|
|
@@ -653,7 +653,6 @@ module Dependabot
|
|
|
653
653
|
)
|
|
654
654
|
end
|
|
655
655
|
end
|
|
656
|
-
# rubocop:enable Metrics/ClassLength
|
|
657
656
|
end
|
|
658
657
|
end
|
|
659
658
|
end
|
|
@@ -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
|
|
@@ -132,8 +132,17 @@ module Dependabot
|
|
|
132
132
|
type: type,
|
|
133
133
|
git: type == "git"
|
|
134
134
|
)
|
|
135
|
+
when Array
|
|
136
|
+
repositories = T.let([], T::Array[Repository])
|
|
137
|
+
value.each do |raw_repository|
|
|
138
|
+
repository_value = T.cast(raw_repository, Object)
|
|
139
|
+
parsed_repository = parse_repository(repository_value, version)
|
|
140
|
+
repositories << parsed_repository if parsed_repository
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
repositories.find(&:git?) || repositories.first
|
|
135
144
|
else
|
|
136
|
-
raise TypeError, "version #{version} repository must be a string or
|
|
145
|
+
raise TypeError, "version #{version} repository must be a string, object, or array"
|
|
137
146
|
end
|
|
138
147
|
end
|
|
139
148
|
private_class_method :parse_repository
|
|
@@ -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
|
|
|
@@ -12,7 +12,7 @@ require "dependabot/pull_request_creator/commit_signer"
|
|
|
12
12
|
|
|
13
13
|
module Dependabot
|
|
14
14
|
class PullRequestCreator
|
|
15
|
-
# rubocop:disable Metrics/ClassLength
|
|
15
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
16
16
|
class Github
|
|
17
17
|
extend T::Sig
|
|
18
18
|
include Dependabot::Clients::GithubResourceParser
|
|
@@ -634,6 +634,5 @@ module Dependabot
|
|
|
634
634
|
end
|
|
635
635
|
end
|
|
636
636
|
end
|
|
637
|
-
# rubocop:enable Metrics/ClassLength
|
|
638
637
|
end
|
|
639
638
|
end
|
|
@@ -9,7 +9,7 @@ require "dependabot/credential"
|
|
|
9
9
|
|
|
10
10
|
module Dependabot
|
|
11
11
|
class PullRequestCreator
|
|
12
|
-
# rubocop:disable Metrics/ClassLength
|
|
12
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
13
13
|
class Labeler
|
|
14
14
|
extend T::Sig
|
|
15
15
|
|
|
@@ -155,9 +155,8 @@ module Dependabot
|
|
|
155
155
|
new_version_parts = T.must(version(dep)).split(/[.+]/)
|
|
156
156
|
old_version_parts = previous_version(dep)&.split(/[.+]/) || []
|
|
157
157
|
all_parts = new_version_parts.first(3) + old_version_parts.first(3)
|
|
158
|
-
# rubocop:disable Performance/RedundantEqualityComparisonBlock
|
|
158
|
+
# rubocop:disable-next Performance/RedundantEqualityComparisonBlock
|
|
159
159
|
next 0 unless all_parts.all? { |part| part.to_i.to_s == part }
|
|
160
|
-
# rubocop:enable Performance/RedundantEqualityComparisonBlock
|
|
161
160
|
next 1 if new_version_parts[0] != old_version_parts[0]
|
|
162
161
|
next 2 if new_version_parts[1] != old_version_parts[1]
|
|
163
162
|
|
|
@@ -556,6 +555,5 @@ module Dependabot
|
|
|
556
555
|
Utils.version_class_for_package_manager(package_manager)
|
|
557
556
|
end
|
|
558
557
|
end
|
|
559
|
-
# rubocop:enable Metrics/ClassLength
|
|
560
558
|
end
|
|
561
559
|
end
|
|
@@ -14,7 +14,7 @@ require "dependabot/pull_request_creator"
|
|
|
14
14
|
require "dependabot/pull_request_creator/message"
|
|
15
15
|
require "dependabot/notices"
|
|
16
16
|
|
|
17
|
-
# rubocop:disable Metrics/ClassLength
|
|
17
|
+
# rubocop:disable-next Metrics/ClassLength
|
|
18
18
|
module Dependabot
|
|
19
19
|
class PullRequestCreator
|
|
20
20
|
# MessageBuilder builds PR message for a dependency update
|
|
@@ -976,4 +976,3 @@ module Dependabot
|
|
|
976
976
|
end
|
|
977
977
|
end
|
|
978
978
|
end
|
|
979
|
-
# rubocop:enable Metrics/ClassLength
|
|
@@ -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
|
|
@@ -147,14 +147,14 @@ dependencies:
|
|
|
147
147
|
requirements:
|
|
148
148
|
- - "<"
|
|
149
149
|
- !ruby/object:Gem::Version
|
|
150
|
-
version: '2.
|
|
150
|
+
version: '2.22'
|
|
151
151
|
type: :runtime
|
|
152
152
|
prerelease: false
|
|
153
153
|
version_requirements: !ruby/object:Gem::Requirement
|
|
154
154
|
requirements:
|
|
155
155
|
- - "<"
|
|
156
156
|
- !ruby/object:Gem::Version
|
|
157
|
-
version: '2.
|
|
157
|
+
version: '2.22'
|
|
158
158
|
- !ruby/object:Gem::Dependency
|
|
159
159
|
name: nokogiri
|
|
160
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -450,19 +450,19 @@ dependencies:
|
|
|
450
450
|
- !ruby/object:Gem::Version
|
|
451
451
|
version: '1.1'
|
|
452
452
|
- !ruby/object:Gem::Dependency
|
|
453
|
-
name:
|
|
453
|
+
name: turbo_tests2
|
|
454
454
|
requirement: !ruby/object:Gem::Requirement
|
|
455
455
|
requirements:
|
|
456
456
|
- - "~>"
|
|
457
457
|
- !ruby/object:Gem::Version
|
|
458
|
-
version:
|
|
458
|
+
version: 3.2.7
|
|
459
459
|
type: :development
|
|
460
460
|
prerelease: false
|
|
461
461
|
version_requirements: !ruby/object:Gem::Requirement
|
|
462
462
|
requirements:
|
|
463
463
|
- - "~>"
|
|
464
464
|
- !ruby/object:Gem::Version
|
|
465
|
-
version:
|
|
465
|
+
version: 3.2.7
|
|
466
466
|
- !ruby/object:Gem::Dependency
|
|
467
467
|
name: vcr
|
|
468
468
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -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
|