dependabot-common 0.245.0 → 0.246.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dependabot/clients/bitbucket.rb +113 -5
- data/lib/dependabot/clients/codecommit.rb +107 -12
- data/lib/dependabot/clients/github_with_retries.rb +61 -19
- data/lib/dependabot/clients/gitlab_with_retries.rb +60 -7
- data/lib/dependabot/dependency.rb +1 -1
- data/lib/dependabot/errors.rb +8 -2
- data/lib/dependabot/git_commit_checker.rb +3 -2
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +1 -1
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +1 -1
- data/lib/dependabot/metadata_finders/base/release_finder.rb +1 -1
- data/lib/dependabot/pull_request_creator/azure.rb +80 -9
- data/lib/dependabot/pull_request_creator/bitbucket.rb +73 -9
- data/lib/dependabot/pull_request_creator/codecommit.rb +96 -25
- data/lib/dependabot/pull_request_creator/github.rb +162 -49
- data/lib/dependabot/pull_request_creator/gitlab.rb +109 -21
- data/lib/dependabot/pull_request_creator/message_builder.rb +239 -89
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +11 -9
- data/lib/dependabot/pull_request_creator.rb +32 -27
- data/lib/dependabot/pull_request_updater/azure.rb +75 -11
- data/lib/dependabot/pull_request_updater/github.rb +89 -28
- data/lib/dependabot/pull_request_updater/gitlab.rb +61 -12
- data/lib/dependabot/pull_request_updater.rb +1 -1
- data/lib/dependabot/update_checkers/base.rb +121 -31
- data/lib/dependabot.rb +1 -1
- metadata +3 -3
@@ -1,7 +1,9 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "pathname"
|
5
|
+
require "sorbet-runtime"
|
6
|
+
|
5
7
|
require "dependabot/clients/github_with_retries"
|
6
8
|
require "dependabot/clients/gitlab_with_retries"
|
7
9
|
require "dependabot/dependency_group"
|
@@ -15,19 +17,72 @@ module Dependabot
|
|
15
17
|
class PullRequestCreator
|
16
18
|
# MessageBuilder builds PR message for a dependency update
|
17
19
|
class MessageBuilder
|
20
|
+
extend T::Sig
|
21
|
+
|
18
22
|
require_relative "message_builder/metadata_presenter"
|
19
23
|
require_relative "message_builder/issue_linker"
|
20
24
|
require_relative "message_builder/link_and_mention_sanitizer"
|
21
25
|
require_relative "pr_name_prefixer"
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
sig { returns(Dependabot::Source) }
|
28
|
+
attr_reader :source
|
29
|
+
|
30
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
31
|
+
attr_reader :dependencies
|
32
|
+
|
33
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
34
|
+
attr_reader :files
|
35
|
+
|
36
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
37
|
+
attr_reader :credentials
|
38
|
+
|
39
|
+
sig { returns(T.nilable(String)) }
|
40
|
+
attr_reader :pr_message_header
|
41
|
+
|
42
|
+
sig { returns(T.nilable(String)) }
|
43
|
+
attr_reader :pr_message_footer
|
44
|
+
|
45
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
46
|
+
attr_reader :commit_message_options
|
47
|
+
|
48
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
49
|
+
attr_reader :vulnerabilities_fixed
|
50
|
+
|
51
|
+
sig { returns(T.nilable(String)) }
|
52
|
+
attr_reader :github_redirection_service
|
53
|
+
|
54
|
+
sig { returns(T.nilable(Dependabot::DependencyGroup)) }
|
55
|
+
attr_reader :dependency_group
|
56
|
+
|
57
|
+
sig { returns(T.nilable(Integer)) }
|
58
|
+
attr_reader :pr_message_max_length
|
59
|
+
|
60
|
+
sig { returns(T.nilable(Encoding)) }
|
61
|
+
attr_reader :pr_message_encoding
|
62
|
+
|
63
|
+
sig { returns(T::Array[T::Hash[String, String]]) }
|
64
|
+
attr_reader :ignore_conditions
|
28
65
|
|
29
66
|
TRUNCATED_MSG = "...\n\n_Description has been truncated_"
|
30
67
|
|
68
|
+
sig do
|
69
|
+
params(
|
70
|
+
source: Dependabot::Source,
|
71
|
+
dependencies: T::Array[Dependabot::Dependency],
|
72
|
+
files: T::Array[Dependabot::DependencyFile],
|
73
|
+
credentials: T::Array[Dependabot::Credential],
|
74
|
+
pr_message_header: T.nilable(String),
|
75
|
+
pr_message_footer: T.nilable(String),
|
76
|
+
commit_message_options: T.nilable(T::Hash[Symbol, T.untyped]),
|
77
|
+
vulnerabilities_fixed: T::Hash[String, T.untyped],
|
78
|
+
github_redirection_service: T.nilable(String),
|
79
|
+
dependency_group: T.nilable(Dependabot::DependencyGroup),
|
80
|
+
pr_message_max_length: T.nilable(Integer),
|
81
|
+
pr_message_encoding: T.nilable(Encoding),
|
82
|
+
ignore_conditions: T::Array[T::Hash[String, String]]
|
83
|
+
)
|
84
|
+
.void
|
85
|
+
end
|
31
86
|
def initialize(source:, dependencies:, files:, credentials:,
|
32
87
|
pr_message_header: nil, pr_message_footer: nil,
|
33
88
|
commit_message_options: {}, vulnerabilities_fixed: {},
|
@@ -48,16 +103,20 @@ module Dependabot
|
|
48
103
|
@ignore_conditions = ignore_conditions
|
49
104
|
end
|
50
105
|
|
106
|
+
sig { params(pr_message_max_length: Integer).returns(Integer) }
|
51
107
|
attr_writer :pr_message_max_length
|
52
108
|
|
109
|
+
sig { params(pr_message_encoding: Encoding).returns(Encoding) }
|
53
110
|
attr_writer :pr_message_encoding
|
54
111
|
|
112
|
+
sig { returns(String) }
|
55
113
|
def pr_name
|
56
114
|
name = dependency_group ? group_pr_name : solo_pr_name
|
57
|
-
name[0] = name[0].capitalize if pr_name_prefixer.capitalize_first_word?
|
115
|
+
name[0] = T.must(name[0]).capitalize if pr_name_prefixer.capitalize_first_word?
|
58
116
|
"#{pr_name_prefix}#{name}"
|
59
117
|
end
|
60
118
|
|
119
|
+
sig { returns(String) }
|
61
120
|
def pr_message
|
62
121
|
msg = "#{suffixed_pr_message_header}" \
|
63
122
|
"#{commit_message_intro}" \
|
@@ -73,35 +132,42 @@ module Dependabot
|
|
73
132
|
|
74
133
|
# Truncate PR message as determined by the pr_message_max_length and pr_message_encoding instance variables
|
75
134
|
# The encoding is used when calculating length, all messages are returned as ruby UTF_8 encoded string
|
135
|
+
sig { params(msg: String).returns(String) }
|
76
136
|
def truncate_pr_message(msg)
|
77
137
|
return msg if pr_message_max_length.nil?
|
78
138
|
|
79
139
|
msg = msg.dup
|
80
|
-
msg = msg.force_encoding(pr_message_encoding) unless pr_message_encoding.nil?
|
140
|
+
msg = msg.force_encoding(T.must(pr_message_encoding)) unless pr_message_encoding.nil?
|
81
141
|
|
82
|
-
if msg.length > pr_message_max_length
|
83
|
-
tr_msg = pr_message_encoding.nil?
|
84
|
-
|
85
|
-
|
142
|
+
if msg.length > T.must(pr_message_max_length)
|
143
|
+
tr_msg = if pr_message_encoding.nil?
|
144
|
+
TRUNCATED_MSG
|
145
|
+
else
|
146
|
+
(+TRUNCATED_MSG).dup.force_encoding(T.must(pr_message_encoding))
|
147
|
+
end
|
148
|
+
trunc_length = T.must(pr_message_max_length) - tr_msg.length
|
149
|
+
msg = (T.must(msg[0..trunc_length]) + tr_msg)
|
86
150
|
end
|
87
151
|
# if we used a custom encoding for calculating length, then we need to force back to UTF-8
|
88
152
|
msg = msg.encode("utf-8", "binary", invalid: :replace, undef: :replace) unless pr_message_encoding.nil?
|
89
153
|
msg
|
90
154
|
end
|
91
155
|
|
156
|
+
sig { returns(String) }
|
92
157
|
def commit_message
|
93
158
|
message = commit_subject + "\n\n"
|
94
159
|
message += commit_message_intro
|
95
160
|
message += metadata_links
|
96
|
-
message += "\n\n" + message_trailers if message_trailers
|
161
|
+
message += "\n\n" + T.must(message_trailers) if message_trailers
|
97
162
|
message
|
98
163
|
rescue StandardError => e
|
99
164
|
Dependabot.logger.error("Error while generating commit message: #{e.message}")
|
100
165
|
message = commit_subject
|
101
|
-
message += "\n\n" + message_trailers if message_trailers
|
166
|
+
message += "\n\n" + T.must(message_trailers) if message_trailers
|
102
167
|
message
|
103
168
|
end
|
104
169
|
|
170
|
+
sig { returns(Dependabot::PullRequestCreator::Message) }
|
105
171
|
def message
|
106
172
|
Dependabot::PullRequestCreator::Message.new(
|
107
173
|
pr_name: pr_name,
|
@@ -112,65 +178,74 @@ module Dependabot
|
|
112
178
|
|
113
179
|
private
|
114
180
|
|
181
|
+
sig { returns(String) }
|
115
182
|
def solo_pr_name
|
116
183
|
name = library? ? library_pr_name : application_pr_name
|
117
184
|
"#{name}#{pr_name_directory}"
|
118
185
|
end
|
119
186
|
|
187
|
+
sig { returns(String) }
|
120
188
|
def library_pr_name
|
121
189
|
"update " +
|
122
190
|
if dependencies.count == 1
|
123
|
-
"#{dependencies.first.display_name} requirement " \
|
124
|
-
"#{from_version_msg(old_library_requirement(dependencies.first))}" \
|
125
|
-
"to #{new_library_requirement(dependencies.first)}"
|
191
|
+
"#{T.must(dependencies.first).display_name} requirement " \
|
192
|
+
"#{from_version_msg(old_library_requirement(T.must(dependencies.first)))}" \
|
193
|
+
"to #{new_library_requirement(T.must(dependencies.first))}"
|
126
194
|
else
|
127
195
|
names = dependencies.map(&:name).uniq
|
128
196
|
if names.count == 1
|
129
197
|
"requirements for #{names.first}"
|
130
198
|
else
|
131
|
-
"requirements for #{names[0..-2].join(', ')} and #{names[-1]}"
|
199
|
+
"requirements for #{T.must(names[0..-2]).join(', ')} and #{names[-1]}"
|
132
200
|
end
|
133
201
|
end
|
134
202
|
end
|
135
203
|
|
204
|
+
# rubocop:disable Metrics/AbcSize
|
205
|
+
sig { returns(String) }
|
136
206
|
def application_pr_name
|
137
207
|
"bump " +
|
138
208
|
if dependencies.count == 1
|
139
209
|
dependency = dependencies.first
|
140
|
-
"#{dependency.display_name} " \
|
141
|
-
"#{from_version_msg(dependency.humanized_previous_version)}" \
|
142
|
-
"to #{dependency.humanized_version}"
|
210
|
+
"#{T.must(dependency).display_name} " \
|
211
|
+
"#{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
212
|
+
"to #{T.must(dependency).humanized_version}"
|
143
213
|
elsif updating_a_property?
|
144
214
|
dependency = dependencies.first
|
145
215
|
"#{property_name} " \
|
146
|
-
"#{from_version_msg(dependency.humanized_previous_version)}" \
|
147
|
-
"to #{dependency.humanized_version}"
|
216
|
+
"#{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
217
|
+
"to #{T.must(dependency).humanized_version}"
|
148
218
|
elsif updating_a_dependency_set?
|
149
219
|
dependency = dependencies.first
|
150
220
|
"#{dependency_set.fetch(:group)} dependency set " \
|
151
|
-
"#{from_version_msg(dependency.humanized_previous_version)}" \
|
152
|
-
"to #{dependency.humanized_version}"
|
221
|
+
"#{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
222
|
+
"to #{T.must(dependency).humanized_version}"
|
153
223
|
else
|
154
224
|
names = dependencies.map(&:name).uniq
|
155
225
|
if names.count == 1
|
156
|
-
names.first
|
226
|
+
T.must(names.first)
|
157
227
|
else
|
158
|
-
"#{names[0..-2].join(', ')} and #{names[-1]}"
|
228
|
+
"#{T.must(names[0..-2]).join(', ')} and #{names[-1]}"
|
159
229
|
end
|
160
230
|
end
|
161
231
|
end
|
232
|
+
# rubocop:enable Metrics/AbcSize
|
162
233
|
|
234
|
+
sig { returns(String) }
|
163
235
|
def group_pr_name
|
164
236
|
updates = dependencies.map(&:name).uniq.count
|
165
237
|
|
166
|
-
if source
|
167
|
-
"bump the #{dependency_group.name} across #{source.directories.count} directories " \
|
238
|
+
if source.directories
|
239
|
+
"bump the #{T.must(dependency_group).name} across #{T.must(source.directories).count} directories " \
|
168
240
|
"with #{updates} update#{'s' if updates > 1}"
|
169
241
|
else
|
170
|
-
"bump the #{dependency_group.name} group#{pr_name_directory} with #{updates} update#{
|
242
|
+
"bump the #{T.must(dependency_group).name} group#{pr_name_directory} with #{updates} update#{if updates > 1
|
243
|
+
's'
|
244
|
+
end}"
|
171
245
|
end
|
172
246
|
end
|
173
247
|
|
248
|
+
sig { returns(String) }
|
174
249
|
def pr_name_prefix
|
175
250
|
pr_name_prefixer.pr_name_prefix
|
176
251
|
rescue StandardError => e
|
@@ -178,12 +253,14 @@ module Dependabot
|
|
178
253
|
""
|
179
254
|
end
|
180
255
|
|
256
|
+
sig { returns(String) }
|
181
257
|
def pr_name_directory
|
182
|
-
return "" if files.first.directory == "/"
|
258
|
+
return "" if T.must(files.first).directory == "/"
|
183
259
|
|
184
|
-
" in #{files.first.directory}"
|
260
|
+
" in #{T.must(files.first).directory}"
|
185
261
|
end
|
186
262
|
|
263
|
+
sig { returns(String) }
|
187
264
|
def commit_subject
|
188
265
|
subject = pr_name.gsub("⬆️", ":arrow_up:").gsub("🔒", ":lock:")
|
189
266
|
return subject unless subject.length > 72
|
@@ -191,57 +268,65 @@ module Dependabot
|
|
191
268
|
subject = subject.gsub(/ from [^\s]*? to [^\s]*/, "")
|
192
269
|
return subject unless subject.length > 72
|
193
270
|
|
194
|
-
subject.split(" in ").first
|
271
|
+
T.must(subject.split(" in ").first)
|
195
272
|
end
|
196
273
|
|
274
|
+
sig { returns(String) }
|
197
275
|
def commit_message_intro
|
198
276
|
return requirement_commit_message_intro if library?
|
199
277
|
|
200
278
|
version_commit_message_intro
|
201
279
|
end
|
202
280
|
|
281
|
+
sig { returns(String) }
|
203
282
|
def prefixed_pr_message_footer
|
204
283
|
return "" unless pr_message_footer
|
205
284
|
|
206
285
|
"\n\n#{pr_message_footer}"
|
207
286
|
end
|
208
287
|
|
288
|
+
sig { returns(String) }
|
209
289
|
def suffixed_pr_message_header
|
210
290
|
return "" unless pr_message_header
|
211
291
|
|
212
292
|
"#{pr_message_header}\n\n"
|
213
293
|
end
|
214
294
|
|
295
|
+
sig { returns(T.nilable(String)) }
|
215
296
|
def message_trailers
|
216
297
|
return unless signoff_trailers || custom_trailers
|
217
298
|
|
218
299
|
[signoff_trailers, custom_trailers].compact.join("\n")
|
219
300
|
end
|
220
301
|
|
302
|
+
sig { returns(T.nilable(String)) }
|
221
303
|
def custom_trailers
|
222
|
-
trailers = commit_message_options
|
304
|
+
trailers = commit_message_options&.dig(:trailers)
|
223
305
|
return if trailers.nil?
|
224
306
|
raise("Commit trailers must be a Hash object") unless trailers.is_a?(Hash)
|
225
307
|
|
226
308
|
trailers.compact.map { |k, v| "#{k}: #{v}" }.join("\n")
|
227
309
|
end
|
228
310
|
|
311
|
+
sig { returns(T.nilable(String)) }
|
229
312
|
def signoff_trailers
|
230
313
|
return unless on_behalf_of_message || signoff_message
|
231
314
|
|
232
315
|
[on_behalf_of_message, signoff_message].compact.join("\n")
|
233
316
|
end
|
234
317
|
|
318
|
+
sig { returns(T.nilable(String)) }
|
235
319
|
def signoff_message
|
236
|
-
signoff_details = commit_message_options
|
320
|
+
signoff_details = commit_message_options&.dig(:signoff_details)
|
237
321
|
return unless signoff_details.is_a?(Hash)
|
238
322
|
return unless signoff_details[:name] && signoff_details[:email]
|
239
323
|
|
240
324
|
"Signed-off-by: #{signoff_details[:name]} <#{signoff_details[:email]}>"
|
241
325
|
end
|
242
326
|
|
327
|
+
sig { returns(T.nilable(String)) }
|
243
328
|
def on_behalf_of_message
|
244
|
-
signoff_details = commit_message_options
|
329
|
+
signoff_details = commit_message_options&.dig(:signoff_details)
|
245
330
|
return unless signoff_details.is_a?(Hash)
|
246
331
|
return unless signoff_details[:org_name] && signoff_details[:org_email]
|
247
332
|
|
@@ -249,6 +334,7 @@ module Dependabot
|
|
249
334
|
"<#{signoff_details[:org_email]}>"
|
250
335
|
end
|
251
336
|
|
337
|
+
sig { returns(String) }
|
252
338
|
def requirement_commit_message_intro
|
253
339
|
msg = "Updates the requirements on "
|
254
340
|
|
@@ -256,7 +342,7 @@ module Dependabot
|
|
256
342
|
if dependencies.count == 1
|
257
343
|
"#{dependency_links.first} "
|
258
344
|
else
|
259
|
-
"#{dependency_links[0..-2].join(', ')} and #{dependency_links[-1]} "
|
345
|
+
"#{T.must(dependency_links[0..-2]).join(', ')} and #{dependency_links[-1]} "
|
260
346
|
end
|
261
347
|
|
262
348
|
msg + "to permit the latest version."
|
@@ -265,8 +351,9 @@ module Dependabot
|
|
265
351
|
# rubocop:disable Metrics/CyclomaticComplexity
|
266
352
|
# rubocop:disable Metrics/PerceivedComplexity
|
267
353
|
# rubocop:disable Metrics/AbcSize
|
354
|
+
sig { returns(String) }
|
268
355
|
def version_commit_message_intro
|
269
|
-
return multi_directory_group_intro if dependency_group && source
|
356
|
+
return multi_directory_group_intro if dependency_group && source.directories
|
270
357
|
|
271
358
|
return group_intro if dependency_group
|
272
359
|
|
@@ -283,14 +370,16 @@ module Dependabot
|
|
283
370
|
|
284
371
|
dependency = dependencies.first
|
285
372
|
msg = "Bumps #{dependency_links.first} " \
|
286
|
-
"#{from_version_msg(dependency.humanized_previous_version)}" \
|
287
|
-
"to #{dependency.humanized_version}."
|
373
|
+
"#{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
374
|
+
"to #{T.must(dependency).humanized_version}."
|
288
375
|
|
289
|
-
|
376
|
+
if switching_from_ref_to_release?(T.must(dependency))
|
377
|
+
msg += " This release includes the previously tagged commit."
|
378
|
+
end
|
290
379
|
|
291
|
-
if vulnerabilities_fixed[dependency.name]&.one?
|
380
|
+
if vulnerabilities_fixed[T.must(dependency).name]&.one?
|
292
381
|
msg += " **This update includes a security fix.**"
|
293
|
-
elsif vulnerabilities_fixed[dependency.name]&.any?
|
382
|
+
elsif vulnerabilities_fixed[T.must(dependency).name]&.any?
|
294
383
|
msg += " **This update includes security fixes.**"
|
295
384
|
end
|
296
385
|
|
@@ -300,35 +389,39 @@ module Dependabot
|
|
300
389
|
# rubocop:enable Metrics/PerceivedComplexity
|
301
390
|
# rubocop:enable Metrics/AbcSize
|
302
391
|
|
392
|
+
sig { returns(String) }
|
303
393
|
def multidependency_property_intro
|
304
394
|
dependency = dependencies.first
|
305
395
|
|
306
396
|
"Bumps `#{property_name}` " \
|
307
|
-
"#{from_version_msg(dependency.humanized_previous_version)}" \
|
308
|
-
"to #{dependency.humanized_version}."
|
397
|
+
"#{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
398
|
+
"to #{T.must(dependency).humanized_version}."
|
309
399
|
end
|
310
400
|
|
401
|
+
sig { returns(String) }
|
311
402
|
def dependency_set_intro
|
312
403
|
dependency = dependencies.first
|
313
404
|
|
314
405
|
"Bumps `#{dependency_set.fetch(:group)}` " \
|
315
|
-
"dependency set #{from_version_msg(dependency.humanized_previous_version)}" \
|
316
|
-
"to #{dependency.humanized_version}."
|
406
|
+
"dependency set #{from_version_msg(T.must(dependency).humanized_previous_version)}" \
|
407
|
+
"to #{T.must(dependency).humanized_version}."
|
317
408
|
end
|
318
409
|
|
410
|
+
sig { returns(String) }
|
319
411
|
def multidependency_intro
|
320
|
-
"Bumps #{dependency_links[0..-2].join(', ')} " \
|
412
|
+
"Bumps #{T.must(dependency_links[0..-2]).join(', ')} " \
|
321
413
|
"and #{dependency_links[-1]}. These " \
|
322
414
|
"dependencies needed to be updated together."
|
323
415
|
end
|
324
416
|
|
417
|
+
sig { returns(String) }
|
325
418
|
def transitive_multidependency_intro
|
326
419
|
dependency = dependencies.first
|
327
420
|
|
328
|
-
msg = "Bumps #{dependency_links[0]} to #{dependency.humanized_version}"
|
421
|
+
msg = "Bumps #{dependency_links[0]} to #{T.must(dependency).humanized_version}"
|
329
422
|
|
330
423
|
msg += if dependencies.count > 2
|
331
|
-
" and updates ancestor dependencies #{dependency_links[0..-2].join(', ')} " \
|
424
|
+
" and updates ancestor dependencies #{T.must(dependency_links[0..-2]).join(', ')} " \
|
332
425
|
"and #{dependency_links[-1]}. "
|
333
426
|
else
|
334
427
|
" and updates ancestor dependency #{dependency_links[1]}. "
|
@@ -339,11 +432,12 @@ module Dependabot
|
|
339
432
|
msg
|
340
433
|
end
|
341
434
|
|
435
|
+
sig { returns(String) }
|
342
436
|
def transitive_removed_dependency_intro
|
343
437
|
msg = "Removes #{dependency_links[0]}. It's no longer used after updating"
|
344
438
|
|
345
439
|
msg += if dependencies.count > 2
|
346
|
-
" ancestor dependencies #{dependency_links[0..-2].join(', ')} " \
|
440
|
+
" ancestor dependencies #{T.must(dependency_links[0..-2]).join(', ')} " \
|
347
441
|
"and #{dependency_links[-1]}. "
|
348
442
|
else
|
349
443
|
" ancestor dependency #{dependency_links[1]}. "
|
@@ -354,16 +448,18 @@ module Dependabot
|
|
354
448
|
msg
|
355
449
|
end
|
356
450
|
|
451
|
+
# rubocop:disable Metrics/AbcSize
|
452
|
+
sig { returns(String) }
|
357
453
|
def multi_directory_group_intro
|
358
454
|
msg = ""
|
359
455
|
|
360
|
-
source.directories.each do |directory|
|
456
|
+
T.must(source.directories).each do |directory|
|
361
457
|
dependencies_in_directory = dependencies.select { |dep| dep.metadata[:directory] == directory }
|
362
458
|
next unless dependencies_in_directory.any?
|
363
459
|
|
364
460
|
update_count = dependencies_in_directory.map(&:name).uniq.count
|
365
461
|
|
366
|
-
msg += "Bumps the #{dependency_group.name} " \
|
462
|
+
msg += "Bumps the #{T.must(dependency_group).name} " \
|
367
463
|
"with #{update_count} update#{update_count > 1 ? 's' : ''} in the #{directory} directory:"
|
368
464
|
|
369
465
|
msg += if update_count >= 5
|
@@ -378,10 +474,11 @@ module Dependabot
|
|
378
474
|
"\n\n#{table([header] + rows)}"
|
379
475
|
elsif update_count > 1
|
380
476
|
dependency_links_in_directory = dependency_links_for_directory(directory)
|
381
|
-
" #{dependency_links_in_directory[0..-2].join(', ')}
|
477
|
+
" #{T.must(T.must(dependency_links_in_directory)[0..-2]).join(', ')}" \
|
478
|
+
" and #{T.must(dependency_links_in_directory)[-1]}."
|
382
479
|
else
|
383
480
|
dependency_links_in_directory = dependency_links_for_directory(directory)
|
384
|
-
" #{dependency_links_in_directory.first}."
|
481
|
+
" #{T.must(dependency_links_in_directory).first}."
|
385
482
|
end
|
386
483
|
|
387
484
|
msg += "\n"
|
@@ -389,11 +486,13 @@ module Dependabot
|
|
389
486
|
|
390
487
|
msg
|
391
488
|
end
|
489
|
+
# rubocop:enable Metrics/AbcSize
|
392
490
|
|
491
|
+
sig { returns(String) }
|
393
492
|
def group_intro
|
394
493
|
update_count = dependencies.map(&:name).uniq.count
|
395
494
|
|
396
|
-
msg = "Bumps the #{dependency_group.name} group#{pr_name_directory} " \
|
495
|
+
msg = "Bumps the #{T.must(dependency_group).name} group#{pr_name_directory} " \
|
397
496
|
"with #{update_count} update#{update_count > 1 ? 's' : ''}:"
|
398
497
|
|
399
498
|
msg += if update_count >= 5
|
@@ -407,7 +506,7 @@ module Dependabot
|
|
407
506
|
end
|
408
507
|
"\n\n#{table([header] + rows)}"
|
409
508
|
elsif update_count > 1
|
410
|
-
" #{dependency_links[0..-2].join(', ')} and #{dependency_links[-1]}."
|
509
|
+
" #{T.must(dependency_links[0..-2]).join(', ')} and #{dependency_links[-1]}."
|
411
510
|
else
|
412
511
|
" #{dependency_links.first}."
|
413
512
|
end
|
@@ -417,66 +516,86 @@ module Dependabot
|
|
417
516
|
msg
|
418
517
|
end
|
419
518
|
|
519
|
+
sig { params(previous_version: T.nilable(String)).returns(String) }
|
420
520
|
def from_version_msg(previous_version)
|
421
521
|
return "" unless previous_version
|
422
522
|
|
423
523
|
"from #{previous_version} "
|
424
524
|
end
|
425
525
|
|
526
|
+
sig { returns(T::Boolean) }
|
426
527
|
def updating_a_property?
|
427
|
-
dependencies.first
|
428
|
-
|
429
|
-
|
528
|
+
T.must(dependencies.first)
|
529
|
+
.requirements
|
530
|
+
.any? { |r| r.dig(:metadata, :property_name) }
|
430
531
|
end
|
431
532
|
|
533
|
+
sig { returns(T::Boolean) }
|
432
534
|
def updating_a_dependency_set?
|
433
|
-
dependencies.first
|
434
|
-
|
435
|
-
|
535
|
+
T.must(dependencies.first)
|
536
|
+
.requirements
|
537
|
+
.any? { |r| r.dig(:metadata, :dependency_set) }
|
436
538
|
end
|
437
539
|
|
540
|
+
sig { returns(T::Boolean) }
|
438
541
|
def removing_a_transitive_dependency?
|
439
542
|
dependencies.any?(&:removed?)
|
440
543
|
end
|
441
544
|
|
545
|
+
sig { returns(T::Boolean) }
|
442
546
|
def updating_top_level_and_transitive_dependencies?
|
443
547
|
dependencies.any?(&:top_level?) &&
|
444
548
|
dependencies.any? { |dep| !dep.top_level? }
|
445
549
|
end
|
446
550
|
|
551
|
+
sig { returns(String) }
|
447
552
|
def property_name
|
448
|
-
@property_name ||=
|
449
|
-
|
450
|
-
|
553
|
+
@property_name ||=
|
554
|
+
T.let(
|
555
|
+
dependencies.first
|
556
|
+
&.requirements
|
557
|
+
&.find { |r| r.dig(:metadata, :property_name) }
|
558
|
+
&.dig(:metadata, :property_name),
|
559
|
+
T.nilable(String)
|
560
|
+
)
|
451
561
|
|
452
562
|
raise "No property name!" unless @property_name
|
453
563
|
|
454
564
|
@property_name
|
455
565
|
end
|
456
566
|
|
567
|
+
sig { returns(T::Hash[Symbol, String]) }
|
457
568
|
def dependency_set
|
458
|
-
@dependency_set ||=
|
459
|
-
|
460
|
-
|
569
|
+
@dependency_set ||=
|
570
|
+
T.let(
|
571
|
+
dependencies.first
|
572
|
+
&.requirements
|
573
|
+
&.find { |r| r.dig(:metadata, :dependency_set) }
|
574
|
+
&.dig(:metadata, :dependency_set),
|
575
|
+
T.nilable(T.nilable(T::Hash[Symbol, String]))
|
576
|
+
)
|
461
577
|
|
462
578
|
raise "No dependency set!" unless @dependency_set
|
463
579
|
|
464
580
|
@dependency_set
|
465
581
|
end
|
466
582
|
|
583
|
+
sig { returns(T::Array[String]) }
|
467
584
|
def dependency_links
|
468
|
-
return @dependency_links if defined?(@dependency_links)
|
585
|
+
return T.must(@dependency_links) if defined?(@dependency_links)
|
469
586
|
|
470
587
|
uniq_deps = dependencies.each_with_object({}) { |dep, memo| memo[dep.name] ||= dep }.values
|
471
588
|
@dependency_links = uniq_deps.map { |dep| dependency_link(dep) }
|
472
589
|
end
|
473
590
|
|
591
|
+
sig { params(directory: String).returns(T.nilable(T::Array[String])) }
|
474
592
|
def dependency_links_for_directory(directory)
|
475
593
|
dependencies_in_directory = dependencies.select { |dep| dep.metadata[:directory] == directory }
|
476
594
|
uniq_deps = dependencies_in_directory.each_with_object({}) { |dep, memo| memo[dep.name] ||= dep }.values
|
477
|
-
@dependency_links = uniq_deps.map { |dep| dependency_link(dep) }
|
595
|
+
@dependency_links = T.let(uniq_deps.map { |dep| dependency_link(dep) }, T.nilable(T::Array[String]))
|
478
596
|
end
|
479
597
|
|
598
|
+
sig { params(dependency: Dependabot::Dependency).returns(String) }
|
480
599
|
def dependency_link(dependency)
|
481
600
|
if source_url(dependency)
|
482
601
|
"[#{dependency.display_name}](#{source_url(dependency)})"
|
@@ -487,12 +606,14 @@ module Dependabot
|
|
487
606
|
end
|
488
607
|
end
|
489
608
|
|
609
|
+
sig { params(dependency: Dependabot::Dependency).returns(String) }
|
490
610
|
def dependency_version_update(dependency)
|
491
611
|
"#{dependency.humanized_previous_version} to #{dependency.humanized_version}"
|
492
612
|
end
|
493
613
|
|
614
|
+
sig { returns(String) }
|
494
615
|
def metadata_links
|
495
|
-
return metadata_links_for_dep(dependencies.first) if dependencies.count == 1 && dependency_group.nil?
|
616
|
+
return metadata_links_for_dep(T.must(dependencies.first)) if dependencies.count == 1 && dependency_group.nil?
|
496
617
|
|
497
618
|
dependencies.map do |dep|
|
498
619
|
if dep.removed?
|
@@ -506,6 +627,7 @@ module Dependabot
|
|
506
627
|
end.join
|
507
628
|
end
|
508
629
|
|
630
|
+
sig { params(dep: Dependabot::Dependency).returns(String) }
|
509
631
|
def metadata_links_for_dep(dep)
|
510
632
|
msg = ""
|
511
633
|
msg += "\n- [Release notes](#{releases_url(dep)})" if releases_url(dep)
|
@@ -515,13 +637,15 @@ module Dependabot
|
|
515
637
|
msg
|
516
638
|
end
|
517
639
|
|
640
|
+
sig { params(rows: T::Array[T::Array[String]]).returns(String) }
|
518
641
|
def table(rows)
|
519
642
|
[
|
520
|
-
table_header(rows[0]),
|
521
|
-
rows[1..].map { |r| table_row(r) }
|
643
|
+
table_header(T.must(rows[0])),
|
644
|
+
T.must(rows[1..]).map { |r| table_row(r) }
|
522
645
|
].join("\n")
|
523
646
|
end
|
524
647
|
|
648
|
+
sig { params(row: T::Array[String]).returns(String) }
|
525
649
|
def table_header(row)
|
526
650
|
[
|
527
651
|
table_row(row),
|
@@ -529,12 +653,14 @@ module Dependabot
|
|
529
653
|
].join("\n")
|
530
654
|
end
|
531
655
|
|
656
|
+
sig { params(row: T::Array[String]).returns(String) }
|
532
657
|
def table_row(row)
|
533
658
|
"| #{row.join(' | ')} |"
|
534
659
|
end
|
535
660
|
|
661
|
+
sig { returns(String) }
|
536
662
|
def metadata_cascades # rubocop:disable Metrics/PerceivedComplexity
|
537
|
-
return metadata_cascades_for_dep(dependencies.first) if dependencies.one? && !dependency_group
|
663
|
+
return metadata_cascades_for_dep(T.must(dependencies.first)) if dependencies.one? && !dependency_group
|
538
664
|
|
539
665
|
dependencies.map do |dep|
|
540
666
|
msg = if dep.removed?
|
@@ -555,6 +681,7 @@ module Dependabot
|
|
555
681
|
end.join
|
556
682
|
end
|
557
683
|
|
684
|
+
sig { params(dependency: Dependabot::Dependency).returns(String) }
|
558
685
|
def metadata_cascades_for_dep(dependency)
|
559
686
|
return "" if dependency.removed?
|
560
687
|
|
@@ -567,6 +694,7 @@ module Dependabot
|
|
567
694
|
).to_s
|
568
695
|
end
|
569
696
|
|
697
|
+
sig { returns(String) }
|
570
698
|
def ignore_conditions_table
|
571
699
|
# Return an empty string if ignore_conditions is empty
|
572
700
|
return "" if @ignore_conditions.empty?
|
@@ -580,7 +708,9 @@ module Dependabot
|
|
580
708
|
return "" if valid_ignore_conditions.empty?
|
581
709
|
|
582
710
|
# Sort them by updated_at (or created_at if updated_at is nil), taking the latest 20
|
583
|
-
sorted_ignore_conditions = valid_ignore_conditions.sort_by
|
711
|
+
sorted_ignore_conditions = valid_ignore_conditions.sort_by do |ic|
|
712
|
+
ic["updated_at"].nil? ? T.must(ic["created_at"]) : T.must(ic["updated_at"])
|
713
|
+
end.last(20)
|
584
714
|
|
585
715
|
# Map each condition to a row string
|
586
716
|
table_rows = sorted_ignore_conditions.map do |ic|
|
@@ -591,6 +721,7 @@ module Dependabot
|
|
591
721
|
build_table(summary, table_rows)
|
592
722
|
end
|
593
723
|
|
724
|
+
sig { params(summary: String, rows: T::Array[String]).returns(String) }
|
594
725
|
def build_table(summary, rows)
|
595
726
|
table_header = "| Dependency Name | Ignore Conditions |"
|
596
727
|
table_divider = "| --- | --- |"
|
@@ -607,74 +738,87 @@ module Dependabot
|
|
607
738
|
end
|
608
739
|
end
|
609
740
|
|
741
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
610
742
|
def changelog_url(dependency)
|
611
743
|
metadata_finder(dependency).changelog_url
|
612
744
|
end
|
613
745
|
|
746
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
614
747
|
def commits_url(dependency)
|
615
748
|
metadata_finder(dependency).commits_url
|
616
749
|
end
|
617
750
|
|
751
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
618
752
|
def homepage_url(dependency)
|
619
753
|
metadata_finder(dependency).homepage_url
|
620
754
|
end
|
621
755
|
|
756
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
622
757
|
def releases_url(dependency)
|
623
758
|
metadata_finder(dependency).releases_url
|
624
759
|
end
|
625
760
|
|
761
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
626
762
|
def source_url(dependency)
|
627
763
|
metadata_finder(dependency).source_url
|
628
764
|
end
|
629
765
|
|
766
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
630
767
|
def upgrade_url(dependency)
|
631
768
|
metadata_finder(dependency).upgrade_guide_url
|
632
769
|
end
|
633
770
|
|
771
|
+
sig { params(dependency: Dependabot::Dependency).returns(Dependabot::MetadataFinders::Base) }
|
634
772
|
def metadata_finder(dependency)
|
635
|
-
@metadata_finder ||= {}
|
773
|
+
@metadata_finder ||= T.let({}, T.nilable(T::Hash[String, Dependabot::MetadataFinders::Base]))
|
636
774
|
@metadata_finder[dependency.name] ||=
|
637
775
|
MetadataFinders
|
638
776
|
.for_package_manager(dependency.package_manager)
|
639
777
|
.new(dependency: dependency, credentials: credentials)
|
640
778
|
end
|
641
779
|
|
780
|
+
sig { returns(Dependabot::PullRequestCreator::PrNamePrefixer) }
|
642
781
|
def pr_name_prefixer
|
643
782
|
@pr_name_prefixer ||=
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
783
|
+
T.let(
|
784
|
+
PrNamePrefixer.new(
|
785
|
+
source: source,
|
786
|
+
dependencies: dependencies,
|
787
|
+
credentials: credentials,
|
788
|
+
commit_message_options: commit_message_options,
|
789
|
+
security_fix: vulnerabilities_fixed.values.flatten.any?
|
790
|
+
),
|
791
|
+
T.nilable(Dependabot::PullRequestCreator::PrNamePrefixer)
|
650
792
|
)
|
651
793
|
end
|
652
794
|
|
795
|
+
sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
|
653
796
|
def old_library_requirement(dependency)
|
654
797
|
old_reqs =
|
655
|
-
dependency.previous_requirements - dependency.requirements
|
798
|
+
T.must(dependency.previous_requirements) - dependency.requirements
|
656
799
|
|
657
800
|
gemspec =
|
658
801
|
old_reqs.find { |r| r[:file].match?(%r{^[^/]*\.gemspec$}) }
|
659
802
|
return gemspec.fetch(:requirement) if gemspec
|
660
803
|
|
661
|
-
req = old_reqs.first.fetch(:requirement)
|
804
|
+
req = T.must(old_reqs.first).fetch(:requirement)
|
662
805
|
return req if req
|
663
806
|
|
664
807
|
dependency.previous_ref if dependency.ref_changed?
|
665
808
|
end
|
666
809
|
|
810
|
+
sig { params(dependency: Dependabot::Dependency).returns(String) }
|
667
811
|
def new_library_requirement(dependency)
|
668
812
|
updated_reqs =
|
669
|
-
dependency.requirements - dependency.previous_requirements
|
813
|
+
dependency.requirements - T.must(dependency.previous_requirements)
|
670
814
|
|
671
815
|
gemspec =
|
672
816
|
updated_reqs.find { |r| r[:file].match?(%r{^[^/]*\.gemspec$}) }
|
673
817
|
return gemspec.fetch(:requirement) if gemspec
|
674
818
|
|
675
|
-
req = updated_reqs.first.fetch(:requirement)
|
819
|
+
req = T.must(updated_reqs.first).fetch(:requirement)
|
676
820
|
return req if req
|
677
|
-
return dependency.new_ref if dependency.ref_changed? && dependency.new_ref
|
821
|
+
return T.must(dependency.new_ref) if dependency.ref_changed? && dependency.new_ref
|
678
822
|
|
679
823
|
raise "No new requirement!"
|
680
824
|
end
|
@@ -684,6 +828,7 @@ module Dependabot
|
|
684
828
|
# `requirements_update_strategy`.
|
685
829
|
#
|
686
830
|
# TODO reuse in BranchNamer
|
831
|
+
sig { returns(T::Boolean) }
|
687
832
|
def library?
|
688
833
|
# Reject any nested child gemspecs/vendored git dependencies
|
689
834
|
root_files = files.map(&:name)
|
@@ -693,6 +838,7 @@ module Dependabot
|
|
693
838
|
dependencies.any? { |d| d.humanized_previous_version.nil? }
|
694
839
|
end
|
695
840
|
|
841
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
696
842
|
def switching_from_ref_to_release?(dependency)
|
697
843
|
unless dependency.previous_version&.match?(/^[0-9a-f]{40}$/) ||
|
698
844
|
(dependency.previous_version.nil? && dependency.previous_ref)
|
@@ -702,8 +848,12 @@ module Dependabot
|
|
702
848
|
Gem::Version.correct?(dependency.version)
|
703
849
|
end
|
704
850
|
|
851
|
+
sig { returns(String) }
|
705
852
|
def package_manager
|
706
|
-
@package_manager ||=
|
853
|
+
@package_manager ||= T.let(
|
854
|
+
T.must(dependencies.first).package_manager,
|
855
|
+
T.nilable(String)
|
856
|
+
)
|
707
857
|
end
|
708
858
|
end
|
709
859
|
end
|