dependabot-common 0.391.0 → 0.393.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 +42 -22
- data/lib/dependabot/clients/bitbucket.rb +52 -26
- data/lib/dependabot/clients/bitbucket_with_retries.rb +11 -12
- data/lib/dependabot/clients/codecommit.rb +73 -53
- data/lib/dependabot/clients/github_resource_parser.rb +70 -0
- data/lib/dependabot/clients/github_with_retries.rb +63 -23
- data/lib/dependabot/clients/gitlab_with_retries.rb +19 -17
- data/lib/dependabot/clients/json_response_parser.rb +103 -0
- data/lib/dependabot/command_helpers.rb +89 -13
- data/lib/dependabot/credential.rb +12 -3
- data/lib/dependabot/dependency_requirement.rb +28 -15
- data/lib/dependabot/errors.rb +7 -0
- data/lib/dependabot/file_fetchers/base.rb +196 -140
- data/lib/dependabot/file_updaters/vendor_updater.rb +8 -2
- data/lib/dependabot/git_tag_details.rb +8 -14
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +211 -110
- data/lib/dependabot/metadata_finders/base/commit_response_parser.rb +68 -0
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +44 -38
- data/lib/dependabot/pull_request_creator/azure.rb +1 -1
- data/lib/dependabot/pull_request_creator/branch_name_template.rb +1 -1
- data/lib/dependabot/pull_request_creator/codecommit.rb +10 -12
- data/lib/dependabot/pull_request_creator/github.rb +55 -35
- data/lib/dependabot/pull_request_creator/gitlab.rb +37 -11
- data/lib/dependabot/pull_request_creator/labeler.rb +65 -15
- data/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb +21 -2
- data/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +53 -13
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +20 -13
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +179 -78
- data/lib/dependabot/pull_request_updater/azure.rb +63 -11
- data/lib/dependabot/pull_request_updater/github.rb +44 -34
- data/lib/dependabot/pull_request_updater/gitlab.rb +23 -12
- data/lib/dependabot/pull_request_updater.rb +3 -3
- data/lib/dependabot/shared_helpers.rb +107 -39
- data/lib/dependabot/update_checkers/base.rb +9 -5
- data/lib/dependabot/update_checkers/version_filters.rb +5 -0
- data/lib/dependabot/update_checkers/vulnerability_audit.rb +282 -0
- data/lib/dependabot/workspace/git.rb +36 -5
- data/lib/dependabot.rb +1 -1
- metadata +6 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "octokit"
|
|
5
5
|
require "sorbet-runtime"
|
|
6
6
|
|
|
7
7
|
require "dependabot/clients/github_with_retries"
|
|
8
|
+
require "dependabot/clients/github_resource_parser"
|
|
8
9
|
require "dependabot/pull_request_creator/commit_signer"
|
|
9
10
|
require "dependabot/pull_request_updater"
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ module Dependabot
|
|
|
12
13
|
class PullRequestUpdater
|
|
13
14
|
class Github
|
|
14
15
|
extend T::Sig
|
|
16
|
+
include Dependabot::Clients::GithubResourceParser
|
|
15
17
|
|
|
16
18
|
sig { returns(Dependabot::Source) }
|
|
17
19
|
attr_reader :source
|
|
@@ -31,7 +33,7 @@ module Dependabot
|
|
|
31
33
|
sig { returns(Integer) }
|
|
32
34
|
attr_reader :pull_request_number
|
|
33
35
|
|
|
34
|
-
sig { returns(T.nilable(T::Hash[Symbol,
|
|
36
|
+
sig { returns(T.nilable(T::Hash[Symbol, String])) }
|
|
35
37
|
attr_reader :author_details
|
|
36
38
|
|
|
37
39
|
sig { returns(T.nilable(String)) }
|
|
@@ -45,7 +47,7 @@ module Dependabot
|
|
|
45
47
|
files: T::Array[Dependabot::DependencyFile],
|
|
46
48
|
credentials: T::Array[Dependabot::Credential],
|
|
47
49
|
pull_request_number: Integer,
|
|
48
|
-
author_details: T.nilable(T::Hash[Symbol,
|
|
50
|
+
author_details: T.nilable(T::Hash[Symbol, String]),
|
|
49
51
|
signature_key: T.nilable(String),
|
|
50
52
|
commit_message: T.nilable(String)
|
|
51
53
|
)
|
|
@@ -76,7 +78,7 @@ module Dependabot
|
|
|
76
78
|
sig { returns(T.nilable(Sawyer::Resource)) }
|
|
77
79
|
def update
|
|
78
80
|
return unless pull_request_exists?
|
|
79
|
-
return unless branch_exists?(pull_request
|
|
81
|
+
return unless branch_exists?(github_string(github_resource(pull_request, :head, "pull request"), :ref, "head"))
|
|
80
82
|
|
|
81
83
|
commit = create_commit
|
|
82
84
|
branch = update_branch(commit)
|
|
@@ -88,8 +90,10 @@ module Dependabot
|
|
|
88
90
|
|
|
89
91
|
sig { void }
|
|
90
92
|
def update_pull_request_target_branch
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
base = github_resource(pull_request, :base, "pull request")
|
|
94
|
+
base_repo = github_resource(base, :repo, "pull request base")
|
|
95
|
+
target_branch = source.branch || github_string(base_repo, :default_branch, "base repository")
|
|
96
|
+
return if target_branch == github_string(base, :ref, "pull request base")
|
|
93
97
|
|
|
94
98
|
github_client_for_source.update_pull_request(
|
|
95
99
|
source.repo,
|
|
@@ -125,6 +129,11 @@ module Dependabot
|
|
|
125
129
|
)
|
|
126
130
|
end
|
|
127
131
|
|
|
132
|
+
sig { returns(String) }
|
|
133
|
+
def github_response_source
|
|
134
|
+
source.url
|
|
135
|
+
end
|
|
136
|
+
|
|
128
137
|
sig { returns(T::Boolean) }
|
|
129
138
|
def pull_request_exists?
|
|
130
139
|
pull_request
|
|
@@ -133,7 +142,7 @@ module Dependabot
|
|
|
133
142
|
false
|
|
134
143
|
end
|
|
135
144
|
|
|
136
|
-
sig { returns(
|
|
145
|
+
sig { returns(Sawyer::Resource) }
|
|
137
146
|
def pull_request
|
|
138
147
|
@pull_request ||=
|
|
139
148
|
T.let(
|
|
@@ -141,7 +150,7 @@ module Dependabot
|
|
|
141
150
|
source.repo,
|
|
142
151
|
pull_request_number
|
|
143
152
|
),
|
|
144
|
-
T.
|
|
153
|
+
T.nilable(Sawyer::Resource)
|
|
145
154
|
)
|
|
146
155
|
end
|
|
147
156
|
|
|
@@ -153,22 +162,24 @@ module Dependabot
|
|
|
153
162
|
false
|
|
154
163
|
end
|
|
155
164
|
|
|
156
|
-
sig { returns(
|
|
165
|
+
sig { returns(Sawyer::Resource) }
|
|
157
166
|
def create_commit
|
|
158
167
|
tree = create_tree
|
|
159
168
|
|
|
160
|
-
options =
|
|
169
|
+
options = T.let({}, T::Hash[Symbol, Object])
|
|
170
|
+
author = author_details&.dup
|
|
171
|
+
options[:author] = author if author&.any?
|
|
161
172
|
|
|
162
|
-
if
|
|
163
|
-
|
|
164
|
-
options[:signature] = commit_signature(tree,
|
|
173
|
+
if author&.any? && signature_key
|
|
174
|
+
author[:date] = Time.now.utc.iso8601
|
|
175
|
+
options[:signature] = commit_signature(tree, author)
|
|
165
176
|
end
|
|
166
177
|
|
|
167
178
|
begin
|
|
168
179
|
github_client_for_source.create_commit(
|
|
169
180
|
source.repo,
|
|
170
181
|
commit_message,
|
|
171
|
-
tree
|
|
182
|
+
github_string(tree, :sha, "tree"),
|
|
172
183
|
base_commit,
|
|
173
184
|
options
|
|
174
185
|
)
|
|
@@ -186,7 +197,7 @@ module Dependabot
|
|
|
186
197
|
end
|
|
187
198
|
end
|
|
188
199
|
|
|
189
|
-
sig { returns(
|
|
200
|
+
sig { returns(Sawyer::Resource) }
|
|
190
201
|
def create_tree
|
|
191
202
|
file_trees = files.map do |file|
|
|
192
203
|
if file.type == "submodule"
|
|
@@ -238,12 +249,13 @@ module Dependabot
|
|
|
238
249
|
T::Array[Regexp]
|
|
239
250
|
)
|
|
240
251
|
|
|
241
|
-
sig { params(commit:
|
|
252
|
+
sig { params(commit: Sawyer::Resource).returns(T.nilable(Sawyer::Resource)) }
|
|
242
253
|
def update_branch(commit)
|
|
254
|
+
head = github_resource(pull_request, :head, "pull request")
|
|
243
255
|
github_client_for_source.update_ref(
|
|
244
256
|
source.repo,
|
|
245
|
-
"heads/" +
|
|
246
|
-
commit
|
|
257
|
+
"heads/" + github_string(head, :ref, "pull request head"),
|
|
258
|
+
github_string(commit, :sha, "commit"),
|
|
247
259
|
true
|
|
248
260
|
)
|
|
249
261
|
rescue Octokit::UnprocessableEntity => e
|
|
@@ -262,45 +274,43 @@ module Dependabot
|
|
|
262
274
|
return msg unless msg.nil? || msg.empty?
|
|
263
275
|
|
|
264
276
|
fallback_message =
|
|
265
|
-
"#{pull_request
|
|
277
|
+
"#{github_string(pull_request, :title, 'pull request')}" \
|
|
266
278
|
"\n\n" \
|
|
267
279
|
"Dependabot couldn't find the original pull request head commit, " \
|
|
268
280
|
"#{old_commit}."
|
|
269
281
|
|
|
270
282
|
# Take the commit message from the old commit. If the old commit can't
|
|
271
283
|
# be found, use the PR title as the commit message.
|
|
272
|
-
|
|
284
|
+
commit = commit_being_updated
|
|
285
|
+
(commit && github_optional_string(commit, :message, "commit")) || fallback_message
|
|
273
286
|
end
|
|
274
287
|
|
|
275
|
-
sig { returns(T.
|
|
288
|
+
sig { returns(T.nilable(Sawyer::Resource)) }
|
|
276
289
|
def commit_being_updated
|
|
277
290
|
return @commit_being_updated if defined?(@commit_being_updated)
|
|
278
291
|
|
|
279
292
|
@commit_being_updated =
|
|
280
293
|
T.let(
|
|
281
|
-
if pull_request
|
|
294
|
+
if github_integer(pull_request, :commits, "pull request") == 1
|
|
295
|
+
head = github_resource(pull_request, :head, "pull request")
|
|
282
296
|
github_client_for_source
|
|
283
|
-
.git_commit(source.repo,
|
|
297
|
+
.git_commit(source.repo, github_string(head, :sha, "pull request head"))
|
|
284
298
|
else
|
|
285
|
-
commits =
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
commit = commits.find { |c| c.sha == old_commit }
|
|
292
|
-
commit&.commit
|
|
299
|
+
commits = github_client_for_source.pull_request_commits(source.repo, pull_request_number)
|
|
300
|
+
|
|
301
|
+
commit = commits.find { |candidate| github_string(candidate, :sha, "pull request commit") == old_commit }
|
|
302
|
+
commit && github_resource(commit, :commit, "pull request commit")
|
|
293
303
|
end,
|
|
294
|
-
T.
|
|
304
|
+
T.nilable(Sawyer::Resource)
|
|
295
305
|
)
|
|
296
306
|
end
|
|
297
307
|
|
|
298
|
-
sig { params(tree:
|
|
308
|
+
sig { params(tree: Sawyer::Resource, author_details_with_date: T::Hash[Symbol, String]).returns(String) }
|
|
299
309
|
def commit_signature(tree, author_details_with_date)
|
|
300
310
|
PullRequestCreator::CommitSigner.new(
|
|
301
311
|
author_details: author_details_with_date,
|
|
302
312
|
commit_message: commit_message,
|
|
303
|
-
tree_sha: tree
|
|
313
|
+
tree_sha: github_string(tree, :sha, "tree"),
|
|
304
314
|
parent_sha: base_commit,
|
|
305
315
|
signature_key: T.must(signature_key)
|
|
306
316
|
).signature
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "gitlab"
|
|
@@ -7,6 +7,7 @@ require "sorbet-runtime"
|
|
|
7
7
|
require "dependabot/clients/gitlab_with_retries"
|
|
8
8
|
require "dependabot/credential"
|
|
9
9
|
require "dependabot/pull_request_creator"
|
|
10
|
+
require "dependabot/errors"
|
|
10
11
|
|
|
11
12
|
module Dependabot
|
|
12
13
|
class PullRequestUpdater
|
|
@@ -67,10 +68,10 @@ module Dependabot
|
|
|
67
68
|
sig { returns(T.nilable(String)) }
|
|
68
69
|
def update
|
|
69
70
|
return unless merge_request_exists?
|
|
70
|
-
return unless branch_exists?(merge_request
|
|
71
|
+
return unless branch_exists?(gitlab_string(merge_request, "source_branch", "merge request"))
|
|
71
72
|
|
|
72
73
|
create_commit
|
|
73
|
-
merge_request
|
|
74
|
+
gitlab_string(merge_request, "source_branch", "merge request")
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
private
|
|
@@ -83,14 +84,14 @@ module Dependabot
|
|
|
83
84
|
false
|
|
84
85
|
end
|
|
85
86
|
|
|
86
|
-
sig { returns(
|
|
87
|
+
sig { returns(::Gitlab::ObjectifiedHash) }
|
|
87
88
|
def merge_request
|
|
88
89
|
@merge_request ||= T.let(
|
|
89
|
-
|
|
90
|
-
target_project_id || source.repo,
|
|
90
|
+
gitlab_client_for_source.merge_request(
|
|
91
|
+
(target_project_id || source.repo).to_s,
|
|
91
92
|
pull_request_number
|
|
92
93
|
),
|
|
93
|
-
T.
|
|
94
|
+
T.nilable(::Gitlab::ObjectifiedHash)
|
|
94
95
|
)
|
|
95
96
|
end
|
|
96
97
|
|
|
@@ -113,8 +114,7 @@ module Dependabot
|
|
|
113
114
|
false
|
|
114
115
|
end
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
sig { returns(T.untyped) }
|
|
117
|
+
sig { returns(::Gitlab::ObjectifiedHash) }
|
|
118
118
|
def commit_being_updated
|
|
119
119
|
gitlab_client_for_source.commit(source.repo, old_commit)
|
|
120
120
|
end
|
|
@@ -123,11 +123,22 @@ module Dependabot
|
|
|
123
123
|
def create_commit
|
|
124
124
|
gitlab_client_for_source.create_commit(
|
|
125
125
|
source.repo,
|
|
126
|
-
merge_request
|
|
127
|
-
commit_being_updated
|
|
126
|
+
gitlab_string(merge_request, "source_branch", "merge request"),
|
|
127
|
+
gitlab_string(commit_being_updated, "title", "commit"),
|
|
128
128
|
files,
|
|
129
129
|
force: true,
|
|
130
|
-
start_branch: merge_request
|
|
130
|
+
start_branch: gitlab_string(merge_request, "target_branch", "merge request")
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
sig { params(resource: ::Gitlab::ObjectifiedHash, key: String, context: String).returns(String) }
|
|
135
|
+
def gitlab_string(resource, key, context)
|
|
136
|
+
value = T.cast(resource[key], Object)
|
|
137
|
+
return value if value.is_a?(String)
|
|
138
|
+
|
|
139
|
+
raise Dependabot::PrivateSourceBadResponse.new(
|
|
140
|
+
source.url,
|
|
141
|
+
"Malformed GitLab response: #{context} #{key} must be a string"
|
|
131
142
|
)
|
|
132
143
|
end
|
|
133
144
|
end
|
|
@@ -11,6 +11,8 @@ module Dependabot
|
|
|
11
11
|
class PullRequestUpdater
|
|
12
12
|
extend T::Sig
|
|
13
13
|
|
|
14
|
+
UpdateResult = T.type_alias { T.nilable(T.any(Sawyer::Resource, String)) }
|
|
15
|
+
|
|
14
16
|
class BranchProtected < StandardError; end
|
|
15
17
|
|
|
16
18
|
sig { returns(Dependabot::Source) }
|
|
@@ -82,9 +84,7 @@ module Dependabot
|
|
|
82
84
|
@provider_metadata = provider_metadata
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
# We should standardise this to return a `Dependabot::Branch` type instead.
|
|
87
|
-
sig { returns(T.untyped) } # rubocop:disable Sorbet/ForbidTUntyped
|
|
87
|
+
sig { returns(UpdateResult) }
|
|
88
88
|
def update
|
|
89
89
|
case source.provider
|
|
90
90
|
when "github" then github_updater.update
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "digest"
|
|
@@ -23,6 +23,11 @@ module Dependabot
|
|
|
23
23
|
module SharedHelpers # rubocop:disable Metrics/ModuleLength
|
|
24
24
|
extend T::Sig
|
|
25
25
|
|
|
26
|
+
Command = T.type_alias { T.any(String, T::Array[String]) }
|
|
27
|
+
CommandArguments = T.type_alias { T::Array[T.any(String, T::Array[String])] }
|
|
28
|
+
ErrorContext = T.type_alias { T::Hash[Symbol, Object] }
|
|
29
|
+
ExconOptions = T.type_alias { T::Hash[Symbol, Object] }
|
|
30
|
+
HelperResponse = T.type_alias { T::Hash[String, Object] }
|
|
26
31
|
USER_AGENT = T.let(
|
|
27
32
|
"dependabot-core/#{Dependabot::VERSION} " \
|
|
28
33
|
"#{Excon::USER_AGENT} ruby/#{RUBY_VERSION} " \
|
|
@@ -91,7 +96,7 @@ module Dependabot
|
|
|
91
96
|
sig { returns(String) }
|
|
92
97
|
attr_reader :error_class
|
|
93
98
|
|
|
94
|
-
sig { returns(
|
|
99
|
+
sig { returns(ErrorContext) }
|
|
95
100
|
attr_reader :error_context
|
|
96
101
|
|
|
97
102
|
sig { returns(T.nilable(T::Array[String])) }
|
|
@@ -100,7 +105,7 @@ module Dependabot
|
|
|
100
105
|
sig do
|
|
101
106
|
params(
|
|
102
107
|
message: String,
|
|
103
|
-
error_context:
|
|
108
|
+
error_context: ErrorContext,
|
|
104
109
|
error_class: T.nilable(String),
|
|
105
110
|
trace: T.nilable(T::Array[String])
|
|
106
111
|
).void
|
|
@@ -109,11 +114,12 @@ module Dependabot
|
|
|
109
114
|
super(message)
|
|
110
115
|
@error_class = T.let(error_class || "HelperSubprocessFailed", String)
|
|
111
116
|
@error_context = error_context
|
|
112
|
-
|
|
117
|
+
fingerprint = error_context[:fingerprint] || error_context[:command]
|
|
118
|
+
@fingerprint = T.let(fingerprint.is_a?(String) ? fingerprint : nil, T.nilable(String))
|
|
113
119
|
@trace = trace
|
|
114
120
|
end
|
|
115
121
|
|
|
116
|
-
sig { override.returns(
|
|
122
|
+
sig { override.returns(ErrorContext) }
|
|
117
123
|
def sentry_context
|
|
118
124
|
{ fingerprint: [@fingerprint], extra: @error_context.except(:stderr_output, :fingerprint) }
|
|
119
125
|
end
|
|
@@ -125,20 +131,40 @@ module Dependabot
|
|
|
125
131
|
CommandHelpers.escape_command(command)
|
|
126
132
|
end
|
|
127
133
|
|
|
134
|
+
sig do
|
|
135
|
+
params(command: Command, allow_unsafe_shell_command: T::Boolean)
|
|
136
|
+
.returns([CommandArguments, String])
|
|
137
|
+
end
|
|
138
|
+
def self.prepare_command(command, allow_unsafe_shell_command:)
|
|
139
|
+
unless command.is_a?(Array)
|
|
140
|
+
prepared_command = allow_unsafe_shell_command ? command : escape_command(command)
|
|
141
|
+
return [[prepared_command], prepared_command]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
raise ArgumentError, "command must not be empty" if command.empty?
|
|
145
|
+
if allow_unsafe_shell_command
|
|
146
|
+
raise ArgumentError, "allow_unsafe_shell_command cannot be used with an argument vector"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
executable = T.must(command.first)
|
|
150
|
+
[[[executable, executable], *command.drop(1)], Shellwords.join(command)]
|
|
151
|
+
end
|
|
152
|
+
private_class_method :prepare_command
|
|
153
|
+
|
|
128
154
|
# rubocop:disable Metrics/MethodLength
|
|
129
155
|
# rubocop:disable Metrics/AbcSize
|
|
130
156
|
sig do
|
|
131
157
|
params(
|
|
132
158
|
command: String,
|
|
133
159
|
function: String,
|
|
134
|
-
args:
|
|
160
|
+
args: Object,
|
|
135
161
|
env: T.nilable(T::Hash[String, String]),
|
|
136
162
|
stderr_to_stdout: T::Boolean,
|
|
137
163
|
allow_unsafe_shell_command: T::Boolean,
|
|
138
164
|
error_class: T.class_of(HelperSubprocessFailed),
|
|
139
165
|
timeout: Integer
|
|
140
166
|
)
|
|
141
|
-
.returns(
|
|
167
|
+
.returns(Object)
|
|
142
168
|
end
|
|
143
169
|
def self.run_helper_subprocess(
|
|
144
170
|
command:,
|
|
@@ -151,7 +177,7 @@ module Dependabot
|
|
|
151
177
|
timeout: CommandHelpers::TIMEOUTS::DEFAULT
|
|
152
178
|
)
|
|
153
179
|
start = Time.now
|
|
154
|
-
stdin_data = JSON.dump(function: function, args: args)
|
|
180
|
+
stdin_data = T.cast(JSON.dump(function: function, args: args), String)
|
|
155
181
|
cmd = allow_unsafe_shell_command ? command : escape_command(command)
|
|
156
182
|
|
|
157
183
|
# NOTE: For debugging native helpers in specs and dry-run: outputs the
|
|
@@ -160,7 +186,8 @@ module Dependabot
|
|
|
160
186
|
if ENV["DEBUG_FUNCTION"] == function
|
|
161
187
|
puts helper_subprocess_bash_command(stdin_data: stdin_data, command: cmd, env: env)
|
|
162
188
|
# Pause execution so we can run helpers inside the temporary directory
|
|
163
|
-
|
|
189
|
+
require "debug"
|
|
190
|
+
binding.break # rubocop:disable Lint/Debugger
|
|
164
191
|
end
|
|
165
192
|
|
|
166
193
|
env_cmd = [env, cmd].compact
|
|
@@ -199,25 +226,58 @@ module Dependabot
|
|
|
199
226
|
check_out_of_memory_error(stderr, error_context, error_class)
|
|
200
227
|
|
|
201
228
|
begin
|
|
202
|
-
response =
|
|
229
|
+
response = parse_helper_response(stdout)
|
|
203
230
|
return response["result"] if process&.success?
|
|
204
231
|
|
|
232
|
+
message, helper_error_class, trace = parse_helper_error(response)
|
|
233
|
+
|
|
205
234
|
raise error_class.new(
|
|
206
|
-
message:
|
|
207
|
-
error_class:
|
|
235
|
+
message: message,
|
|
236
|
+
error_class: helper_error_class,
|
|
208
237
|
error_context: error_context,
|
|
209
|
-
trace:
|
|
238
|
+
trace: trace
|
|
210
239
|
)
|
|
211
240
|
rescue JSON::ParserError
|
|
212
241
|
raise handle_json_parse_error(stdout, stderr, error_context, error_class)
|
|
242
|
+
rescue TypeError => e
|
|
243
|
+
raise error_class.new(
|
|
244
|
+
message: e.message,
|
|
245
|
+
error_class: e.class.name,
|
|
246
|
+
error_context: error_context
|
|
247
|
+
)
|
|
213
248
|
end
|
|
214
249
|
end
|
|
215
250
|
|
|
251
|
+
sig { params(stdout: String).returns(HelperResponse) }
|
|
252
|
+
def self.parse_helper_response(stdout)
|
|
253
|
+
T.cast(JSON.parse(stdout), HelperResponse)
|
|
254
|
+
end
|
|
255
|
+
private_class_method :parse_helper_response
|
|
256
|
+
|
|
257
|
+
sig { params(response: HelperResponse).returns([String, T.nilable(String), T.nilable(T::Array[String])]) }
|
|
258
|
+
def self.parse_helper_error(response)
|
|
259
|
+
message = response["error"]
|
|
260
|
+
raise TypeError, "helper error must be a string" unless message.is_a?(String)
|
|
261
|
+
|
|
262
|
+
helper_error_class = response["error_class"]
|
|
263
|
+
unless helper_error_class.nil? || helper_error_class.is_a?(String)
|
|
264
|
+
raise TypeError, "helper error class must be a string or nil"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
trace = response["trace"]
|
|
268
|
+
unless trace.nil? || (trace.is_a?(Array) && trace.all?(String))
|
|
269
|
+
raise TypeError, "helper trace must be an array of strings or nil"
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
[message, helper_error_class, T.cast(response["trace"], T.nilable(T::Array[String]))]
|
|
273
|
+
end
|
|
274
|
+
private_class_method :parse_helper_error
|
|
275
|
+
|
|
216
276
|
sig do
|
|
217
277
|
params(
|
|
218
278
|
stdout: String,
|
|
219
279
|
stderr: String,
|
|
220
|
-
error_context:
|
|
280
|
+
error_context: ErrorContext,
|
|
221
281
|
error_class: T.class_of(HelperSubprocessFailed)
|
|
222
282
|
)
|
|
223
283
|
.returns(HelperSubprocessFailed)
|
|
@@ -243,7 +303,7 @@ module Dependabot
|
|
|
243
303
|
sig do
|
|
244
304
|
params(
|
|
245
305
|
stderr: T.nilable(String),
|
|
246
|
-
error_context:
|
|
306
|
+
error_context: ErrorContext,
|
|
247
307
|
error_class: T.class_of(HelperSubprocessFailed)
|
|
248
308
|
).void
|
|
249
309
|
end
|
|
@@ -272,7 +332,7 @@ module Dependabot
|
|
|
272
332
|
}.merge(headers)
|
|
273
333
|
end
|
|
274
334
|
|
|
275
|
-
sig { params(options: T.nilable(
|
|
335
|
+
sig { params(options: T.nilable(ExconOptions)).returns(ExconOptions) }
|
|
276
336
|
def self.excon_defaults(options = nil)
|
|
277
337
|
options ||= {}
|
|
278
338
|
headers = T.cast(options.delete(:headers), T.nilable(T::Hash[String, String]))
|
|
@@ -343,7 +403,6 @@ module Dependabot
|
|
|
343
403
|
File.join(__dir__, "../../bin/git-credential-store-immutable")
|
|
344
404
|
end
|
|
345
405
|
|
|
346
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
347
406
|
sig do
|
|
348
407
|
params(
|
|
349
408
|
credentials: T::Array[Dependabot::Credential],
|
|
@@ -396,27 +455,35 @@ module Dependabot
|
|
|
396
455
|
github_credentials +
|
|
397
456
|
[github_credential].compact
|
|
398
457
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
next unless cred["type"] == "git_source"
|
|
403
|
-
next unless cred["host"]
|
|
458
|
+
File.write(git_store_path, git_store_content(deduped_credentials))
|
|
459
|
+
end
|
|
460
|
+
# rubocop:enable Metrics/AbcSize
|
|
404
461
|
|
|
405
|
-
|
|
462
|
+
sig { params(credentials: T::Array[Credential]).returns(String) }
|
|
463
|
+
def self.git_store_content(credentials)
|
|
464
|
+
credentials.each_with_object(+"") do |credential, content|
|
|
465
|
+
next unless credential["type"] == "git_source"
|
|
406
466
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
authenticated_url = "https://#{creds}#{cred.fetch('host')}"
|
|
467
|
+
host = credential["host"]
|
|
468
|
+
next unless host
|
|
410
469
|
|
|
411
|
-
|
|
412
|
-
|
|
470
|
+
content << authenticated_git_url(
|
|
471
|
+
username: credential["username"],
|
|
472
|
+
password: credential["password"],
|
|
473
|
+
host: host
|
|
474
|
+
) << "\n"
|
|
475
|
+
configure_git_to_use_https(host)
|
|
413
476
|
end
|
|
477
|
+
end
|
|
478
|
+
private_class_method :git_store_content
|
|
414
479
|
|
|
415
|
-
|
|
416
|
-
|
|
480
|
+
sig { params(username: T.nilable(String), password: T.nilable(String), host: String).returns(String) }
|
|
481
|
+
def self.authenticated_git_url(username:, password:, host:)
|
|
482
|
+
credentials = username && password ? "#{username}:#{password}@" : ""
|
|
483
|
+
|
|
484
|
+
"https://#{credentials}#{host}"
|
|
417
485
|
end
|
|
418
|
-
|
|
419
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
486
|
+
private_class_method :authenticated_git_url
|
|
420
487
|
|
|
421
488
|
sig { params(host: String).void }
|
|
422
489
|
def self.configure_git_to_use_https(host)
|
|
@@ -461,10 +528,9 @@ module Dependabot
|
|
|
461
528
|
safe_directories
|
|
462
529
|
end
|
|
463
530
|
|
|
464
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
465
531
|
sig do
|
|
466
532
|
params(
|
|
467
|
-
command:
|
|
533
|
+
command: Command,
|
|
468
534
|
allow_unsafe_shell_command: T::Boolean,
|
|
469
535
|
cwd: T.nilable(String),
|
|
470
536
|
env: T.nilable(T::Hash[String, String]),
|
|
@@ -485,14 +551,17 @@ module Dependabot
|
|
|
485
551
|
output_observer: nil
|
|
486
552
|
)
|
|
487
553
|
start = Time.now
|
|
488
|
-
|
|
554
|
+
command_args, command_for_output = prepare_command(
|
|
555
|
+
command,
|
|
556
|
+
allow_unsafe_shell_command: allow_unsafe_shell_command
|
|
557
|
+
)
|
|
489
558
|
|
|
490
|
-
puts
|
|
559
|
+
puts command_for_output if ENV["DEBUG_HELPERS"] == "true"
|
|
491
560
|
|
|
492
561
|
opts = {}
|
|
493
562
|
opts[:chdir] = cwd if cwd
|
|
494
563
|
|
|
495
|
-
env_cmd = [env || {},
|
|
564
|
+
env_cmd = [env || {}, *command_args, opts].compact
|
|
496
565
|
kwargs = {
|
|
497
566
|
stderr_to_stdout: stderr_to_stdout,
|
|
498
567
|
timeout: timeout
|
|
@@ -511,7 +580,7 @@ module Dependabot
|
|
|
511
580
|
return stdout || "" if process&.success?
|
|
512
581
|
|
|
513
582
|
error_context = {
|
|
514
|
-
command:
|
|
583
|
+
command: command_for_output,
|
|
515
584
|
fingerprint: fingerprint,
|
|
516
585
|
time_taken: time_taken,
|
|
517
586
|
process_exit_value: process.to_s
|
|
@@ -524,7 +593,6 @@ module Dependabot
|
|
|
524
593
|
error_context: error_context
|
|
525
594
|
)
|
|
526
595
|
end
|
|
527
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
528
596
|
|
|
529
597
|
sig { params(stderr: T.nilable(String), error_context: T::Hash[Symbol, String]).void }
|
|
530
598
|
def self.check_out_of_disk_memory_error(stderr, error_context)
|
|
@@ -9,6 +9,7 @@ require "dependabot/security_advisory"
|
|
|
9
9
|
require "dependabot/utils"
|
|
10
10
|
require "dependabot/package/release_cooldown_options"
|
|
11
11
|
require "dependabot/file_filtering"
|
|
12
|
+
require "dependabot/update_checkers/vulnerability_audit"
|
|
12
13
|
|
|
13
14
|
module Dependabot
|
|
14
15
|
module UpdateCheckers
|
|
@@ -168,16 +169,19 @@ module Dependabot
|
|
|
168
169
|
|
|
169
170
|
# Finds any dependencies in the lockfile that have a subdependency on the
|
|
170
171
|
# given dependency that do not satisfy the target_version.
|
|
171
|
-
# @return [Array<Hash{String =>
|
|
172
|
+
# @return [Array<Hash{String => Object}]
|
|
172
173
|
# name [String] the blocking dependencies name
|
|
173
174
|
# version [String] the version of the blocking dependency
|
|
174
175
|
# requirement [String] the requirement on the target_dependency
|
|
175
|
-
sig { overridable.returns(T::Array[
|
|
176
|
+
sig { overridable.returns(T::Array[Dependabot::UpdateCheckers::Conflict]) }
|
|
176
177
|
def conflicting_dependencies
|
|
177
178
|
[] # return an empty array for ecosystems that don't support this yet
|
|
178
179
|
end
|
|
179
180
|
|
|
180
|
-
sig
|
|
181
|
+
sig do
|
|
182
|
+
params(_updated_version: T.any(String, Gem::Version))
|
|
183
|
+
.returns(T.nilable(T.any(String, Gem::Version)))
|
|
184
|
+
end
|
|
181
185
|
def latest_resolvable_previous_version(_updated_version)
|
|
182
186
|
dependency.version
|
|
183
187
|
end
|
|
@@ -253,7 +257,7 @@ module Dependabot
|
|
|
253
257
|
sig { returns(Dependabot::Dependency) }
|
|
254
258
|
def updated_dependency_without_unlock
|
|
255
259
|
version = latest_resolvable_version_with_no_unlock.to_s
|
|
256
|
-
previous_version = latest_resolvable_previous_version(version)
|
|
260
|
+
previous_version = latest_resolvable_previous_version(version)&.to_s
|
|
257
261
|
|
|
258
262
|
Dependency.new(
|
|
259
263
|
name: dependency.name,
|
|
@@ -270,7 +274,7 @@ module Dependabot
|
|
|
270
274
|
sig { returns(Dependabot::Dependency) }
|
|
271
275
|
def updated_dependency_with_own_req_unlock
|
|
272
276
|
version = preferred_resolvable_version.to_s
|
|
273
|
-
previous_version = latest_resolvable_previous_version(version)
|
|
277
|
+
previous_version = latest_resolvable_previous_version(version)&.to_s
|
|
274
278
|
|
|
275
279
|
Dependency.new(
|
|
276
280
|
name: dependency.name,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
require "dependabot/security_advisory"
|
|
5
5
|
require "dependabot/package/package_release"
|
|
6
|
+
require "dependabot/git_tag_details"
|
|
6
7
|
require "sorbet-runtime"
|
|
7
8
|
|
|
8
9
|
module Dependabot
|
|
@@ -22,6 +23,7 @@ module Dependabot
|
|
|
22
23
|
T.any(
|
|
23
24
|
T.all(T.type_parameter(:T), Gem::Version),
|
|
24
25
|
T.all(T.type_parameter(:T), T::Hash[Symbol, Gem::Version]),
|
|
26
|
+
T.all(T.type_parameter(:T), Dependabot::GitTagDetails),
|
|
25
27
|
T.all(T.type_parameter(:T), Dependabot::Package::PackageRelease)
|
|
26
28
|
)],
|
|
27
29
|
security_advisories: T::Array[SecurityAdvisory]
|
|
@@ -35,6 +37,9 @@ module Dependabot
|
|
|
35
37
|
a.vulnerable?(v)
|
|
36
38
|
elsif v.is_a?(Dependabot::Package::PackageRelease)
|
|
37
39
|
a.vulnerable?(v.version)
|
|
40
|
+
elsif v.is_a?(Dependabot::GitTagDetails)
|
|
41
|
+
version = v.version
|
|
42
|
+
version ? a.vulnerable?(version) : false
|
|
38
43
|
else
|
|
39
44
|
a.vulnerable?(v.fetch(:version))
|
|
40
45
|
end
|