dependabot-common 0.236.0 → 0.238.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/azure.rb +3 -3
- data/lib/dependabot/clients/codecommit.rb +1 -0
- data/lib/dependabot/config/file.rb +17 -6
- data/lib/dependabot/config/update_config.rb +23 -5
- data/lib/dependabot/dependency.rb +137 -27
- data/lib/dependabot/dependency_file.rb +84 -14
- data/lib/dependabot/dependency_group.rb +29 -5
- data/lib/dependabot/errors.rb +335 -13
- data/lib/dependabot/file_fetchers/base.rb +227 -93
- data/lib/dependabot/file_updaters/base.rb +1 -1
- data/lib/dependabot/git_commit_checker.rb +6 -0
- data/lib/dependabot/git_metadata_fetcher.rb +58 -20
- data/lib/dependabot/git_ref.rb +71 -0
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +13 -6
- data/lib/dependabot/pull_request_creator/github.rb +11 -8
- data/lib/dependabot/pull_request_creator/message.rb +21 -2
- data/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +37 -16
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +4 -2
- data/lib/dependabot/pull_request_creator/message_builder.rb +54 -4
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +10 -4
- data/lib/dependabot/shared_helpers.rb +117 -33
- data/lib/dependabot/simple_instrumentor.rb +22 -3
- data/lib/dependabot/source.rb +65 -17
- data/lib/dependabot/update_checkers/version_filters.rb +12 -1
- data/lib/dependabot/utils.rb +21 -2
- data/lib/dependabot/workspace/base.rb +42 -7
- data/lib/dependabot/workspace/change_attempt.rb +31 -3
- data/lib/dependabot/workspace/git.rb +34 -4
- data/lib/dependabot/workspace.rb +16 -2
- data/lib/dependabot.rb +1 -1
- metadata +38 -9
data/lib/dependabot/errors.rb
CHANGED
@@ -1,20 +1,234 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
4
5
|
require "dependabot/utils"
|
5
6
|
|
6
7
|
module Dependabot
|
8
|
+
# rubocop:disable Metrics/MethodLength
|
9
|
+
def self.fetcher_error_details(error)
|
10
|
+
case error
|
11
|
+
when Dependabot::ToolVersionNotSupported
|
12
|
+
{
|
13
|
+
"error-type": "tool_version_not_supported",
|
14
|
+
"error-detail": {
|
15
|
+
"tool-name": error.tool_name,
|
16
|
+
"detected-version": error.detected_version,
|
17
|
+
"supported-versions": error.supported_versions
|
18
|
+
}
|
19
|
+
}
|
20
|
+
when Dependabot::BranchNotFound
|
21
|
+
{
|
22
|
+
"error-type": "branch_not_found",
|
23
|
+
"error-detail": { "branch-name": error.branch_name }
|
24
|
+
}
|
25
|
+
when Dependabot::DirectoryNotFound
|
26
|
+
{
|
27
|
+
"error-type": "directory_not_found",
|
28
|
+
"error-detail": { "directory-name": error.directory_name }
|
29
|
+
}
|
30
|
+
when Dependabot::RepoNotFound
|
31
|
+
# This happens if the repo gets removed after a job gets kicked off.
|
32
|
+
# This also happens when a configured personal access token is not authz'd to fetch files from the job repo.
|
33
|
+
{
|
34
|
+
"error-type": "job_repo_not_found",
|
35
|
+
"error-detail": { message: error.message }
|
36
|
+
}
|
37
|
+
when Dependabot::DependencyFileNotParseable
|
38
|
+
{
|
39
|
+
"error-type": "dependency_file_not_parseable",
|
40
|
+
"error-detail": {
|
41
|
+
message: error.message,
|
42
|
+
"file-path": error.file_path
|
43
|
+
}
|
44
|
+
}
|
45
|
+
when Dependabot::DependencyFileNotFound
|
46
|
+
{
|
47
|
+
"error-type": "dependency_file_not_found",
|
48
|
+
"error-detail": { "file-path": error.file_path }
|
49
|
+
}
|
50
|
+
when Dependabot::OutOfDisk
|
51
|
+
{
|
52
|
+
"error-type": "out_of_disk",
|
53
|
+
"error-detail": {}
|
54
|
+
}
|
55
|
+
when Dependabot::PathDependenciesNotReachable
|
56
|
+
{
|
57
|
+
"error-type": "path_dependencies_not_reachable",
|
58
|
+
"error-detail": { dependencies: error.dependencies }
|
59
|
+
}
|
60
|
+
when Octokit::Unauthorized
|
61
|
+
{ "error-type": "octokit_unauthorized" }
|
62
|
+
when Octokit::ServerError
|
63
|
+
# If we get a 500 from GitHub there's very little we can do about it,
|
64
|
+
# and responsibility for fixing it is on them, not us. As a result we
|
65
|
+
# quietly log these as errors
|
66
|
+
{ "error-type": "server_error" }
|
67
|
+
when *Octokit::RATE_LIMITED_ERRORS
|
68
|
+
# If we get a rate-limited error we let dependabot-api handle the
|
69
|
+
# retry by re-enqueing the update job after the reset
|
70
|
+
{
|
71
|
+
"error-type": "octokit_rate_limited",
|
72
|
+
"error-detail": {
|
73
|
+
"rate-limit-reset": error.response_headers["X-RateLimit-Reset"]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.parser_error_details(error)
|
80
|
+
case error
|
81
|
+
when Dependabot::DependencyFileNotEvaluatable
|
82
|
+
{
|
83
|
+
"error-type": "dependency_file_not_evaluatable",
|
84
|
+
"error-detail": { message: error.message }
|
85
|
+
}
|
86
|
+
when Dependabot::DependencyFileNotResolvable
|
87
|
+
{
|
88
|
+
"error-type": "dependency_file_not_resolvable",
|
89
|
+
"error-detail": { message: error.message }
|
90
|
+
}
|
91
|
+
when Dependabot::BranchNotFound
|
92
|
+
{
|
93
|
+
"error-type": "branch_not_found",
|
94
|
+
"error-detail": { "branch-name": error.branch_name }
|
95
|
+
}
|
96
|
+
when Dependabot::DependencyFileNotParseable
|
97
|
+
{
|
98
|
+
"error-type": "dependency_file_not_parseable",
|
99
|
+
"error-detail": {
|
100
|
+
message: error.message,
|
101
|
+
"file-path": error.file_path
|
102
|
+
}
|
103
|
+
}
|
104
|
+
when Dependabot::DependencyFileNotFound
|
105
|
+
{
|
106
|
+
"error-type": "dependency_file_not_found",
|
107
|
+
"error-detail": { "file-path": error.file_path }
|
108
|
+
}
|
109
|
+
when Dependabot::PathDependenciesNotReachable
|
110
|
+
{
|
111
|
+
"error-type": "path_dependencies_not_reachable",
|
112
|
+
"error-detail": { dependencies: error.dependencies }
|
113
|
+
}
|
114
|
+
when Dependabot::PrivateSourceAuthenticationFailure
|
115
|
+
{
|
116
|
+
"error-type": "private_source_authentication_failure",
|
117
|
+
"error-detail": { source: error.source }
|
118
|
+
}
|
119
|
+
when Dependabot::GitDependenciesNotReachable
|
120
|
+
{
|
121
|
+
"error-type": "git_dependencies_not_reachable",
|
122
|
+
"error-detail": { "dependency-urls": error.dependency_urls }
|
123
|
+
}
|
124
|
+
when Dependabot::NotImplemented
|
125
|
+
{
|
126
|
+
"error-type": "not_implemented",
|
127
|
+
"error-detail": {
|
128
|
+
message: error.message
|
129
|
+
}
|
130
|
+
}
|
131
|
+
when Octokit::ServerError
|
132
|
+
# If we get a 500 from GitHub there's very little we can do about it,
|
133
|
+
# and responsibility for fixing it is on them, not us. As a result we
|
134
|
+
# quietly log these as errors
|
135
|
+
{ "error-type": "server_error" }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.updater_error_details(error)
|
140
|
+
case error
|
141
|
+
when Dependabot::DependencyFileNotResolvable
|
142
|
+
{
|
143
|
+
"error-type": "dependency_file_not_resolvable",
|
144
|
+
"error-detail": { message: error.message }
|
145
|
+
}
|
146
|
+
when Dependabot::DependencyFileNotEvaluatable
|
147
|
+
{
|
148
|
+
"error-type": "dependency_file_not_evaluatable",
|
149
|
+
"error-detail": { message: error.message }
|
150
|
+
}
|
151
|
+
when Dependabot::GitDependenciesNotReachable
|
152
|
+
{
|
153
|
+
"error-type": "git_dependencies_not_reachable",
|
154
|
+
"error-detail": { "dependency-urls": error.dependency_urls }
|
155
|
+
}
|
156
|
+
when Dependabot::MisconfiguredTooling
|
157
|
+
{
|
158
|
+
"error-type": "misconfigured_tooling",
|
159
|
+
"error-detail": { "tool-name": error.tool_name, message: error.tool_message }
|
160
|
+
}
|
161
|
+
when Dependabot::GitDependencyReferenceNotFound
|
162
|
+
{
|
163
|
+
"error-type": "git_dependency_reference_not_found",
|
164
|
+
"error-detail": { dependency: error.dependency }
|
165
|
+
}
|
166
|
+
when Dependabot::PrivateSourceAuthenticationFailure
|
167
|
+
{
|
168
|
+
"error-type": "private_source_authentication_failure",
|
169
|
+
"error-detail": { source: error.source }
|
170
|
+
}
|
171
|
+
when Dependabot::PrivateSourceTimedOut
|
172
|
+
{
|
173
|
+
"error-type": "private_source_timed_out",
|
174
|
+
"error-detail": { source: error.source }
|
175
|
+
}
|
176
|
+
when Dependabot::PrivateSourceCertificateFailure
|
177
|
+
{
|
178
|
+
"error-type": "private_source_certificate_failure",
|
179
|
+
"error-detail": { source: error.source }
|
180
|
+
}
|
181
|
+
when Dependabot::MissingEnvironmentVariable
|
182
|
+
{
|
183
|
+
"error-type": "missing_environment_variable",
|
184
|
+
"error-detail": {
|
185
|
+
"environment-variable": error.environment_variable
|
186
|
+
}
|
187
|
+
}
|
188
|
+
when Dependabot::GoModulePathMismatch
|
189
|
+
{
|
190
|
+
"error-type": "go_module_path_mismatch",
|
191
|
+
"error-detail": {
|
192
|
+
"declared-path": error.declared_path,
|
193
|
+
"discovered-path": error.discovered_path,
|
194
|
+
"go-mod": error.go_mod
|
195
|
+
}
|
196
|
+
}
|
197
|
+
when Dependabot::NotImplemented
|
198
|
+
{
|
199
|
+
"error-type": "not_implemented",
|
200
|
+
"error-detail": {
|
201
|
+
message: error.message
|
202
|
+
}
|
203
|
+
}
|
204
|
+
when *Octokit::RATE_LIMITED_ERRORS
|
205
|
+
# If we get a rate-limited error we let dependabot-api handle the
|
206
|
+
# retry by re-enqueing the update job after the reset
|
207
|
+
{
|
208
|
+
"error-type": "octokit_rate_limited",
|
209
|
+
"error-detail": {
|
210
|
+
"rate-limit-reset": error.response_headers["X-RateLimit-Reset"]
|
211
|
+
}
|
212
|
+
}
|
213
|
+
end
|
214
|
+
end
|
215
|
+
# rubocop:enable Metrics/MethodLength
|
216
|
+
|
7
217
|
class DependabotError < StandardError
|
218
|
+
extend T::Sig
|
219
|
+
|
8
220
|
BASIC_AUTH_REGEX = %r{://(?<auth>[^:@]*:[^@%\s/]+(@|%40))}
|
9
221
|
# Remove any path segment from fury.io sources
|
10
222
|
FURY_IO_PATH_REGEX = %r{fury\.io/(?<path>.+)}
|
11
223
|
|
224
|
+
sig { params(message: T.any(T.nilable(String), MatchData)).void }
|
12
225
|
def initialize(message = nil)
|
13
226
|
super(sanitize_message(message))
|
14
227
|
end
|
15
228
|
|
16
229
|
private
|
17
230
|
|
231
|
+
sig { params(message: T.any(T.nilable(String), MatchData)).returns(T.any(T.nilable(String), MatchData)) }
|
18
232
|
def sanitize_message(message)
|
19
233
|
return message unless message.is_a?(String)
|
20
234
|
|
@@ -26,18 +240,25 @@ module Dependabot
|
|
26
240
|
filter_sensitive_data(message)
|
27
241
|
end
|
28
242
|
|
243
|
+
sig { params(message: String).returns(String) }
|
29
244
|
def filter_sensitive_data(message)
|
30
245
|
replace_capture_groups(message, BASIC_AUTH_REGEX, "")
|
31
246
|
end
|
32
247
|
|
248
|
+
sig { params(source: String).returns(String) }
|
33
249
|
def sanitize_source(source)
|
34
250
|
source = filter_sensitive_data(source)
|
35
251
|
replace_capture_groups(source, FURY_IO_PATH_REGEX, "<redacted>")
|
36
252
|
end
|
37
253
|
|
254
|
+
sig do
|
255
|
+
params(
|
256
|
+
string: String,
|
257
|
+
regex: Regexp,
|
258
|
+
replacement: String
|
259
|
+
).returns(String)
|
260
|
+
end
|
38
261
|
def replace_capture_groups(string, regex, replacement)
|
39
|
-
return string unless string.is_a?(String)
|
40
|
-
|
41
262
|
string.scan(regex).flatten.compact.reduce(string) do |original_msg, match|
|
42
263
|
original_msg.gsub(match, replacement)
|
43
264
|
end
|
@@ -55,8 +276,12 @@ module Dependabot
|
|
55
276
|
#####################
|
56
277
|
|
57
278
|
class DirectoryNotFound < DependabotError
|
279
|
+
extend T::Sig
|
280
|
+
|
281
|
+
sig { returns(String) }
|
58
282
|
attr_reader :directory_name
|
59
283
|
|
284
|
+
sig { params(directory_name: String, msg: T.nilable(String)).void }
|
60
285
|
def initialize(directory_name, msg = nil)
|
61
286
|
@directory_name = directory_name
|
62
287
|
super(msg)
|
@@ -64,8 +289,12 @@ module Dependabot
|
|
64
289
|
end
|
65
290
|
|
66
291
|
class BranchNotFound < DependabotError
|
292
|
+
extend T::Sig
|
293
|
+
|
294
|
+
sig { returns(T.nilable(String)) }
|
67
295
|
attr_reader :branch_name
|
68
296
|
|
297
|
+
sig { params(branch_name: T.nilable(String), msg: T.nilable(String)).void }
|
69
298
|
def initialize(branch_name, msg = nil)
|
70
299
|
@branch_name = branch_name
|
71
300
|
super(msg)
|
@@ -73,8 +302,12 @@ module Dependabot
|
|
73
302
|
end
|
74
303
|
|
75
304
|
class RepoNotFound < DependabotError
|
305
|
+
extend T::Sig
|
306
|
+
|
307
|
+
sig { returns(T.any(Dependabot::Source, String)) }
|
76
308
|
attr_reader :source
|
77
309
|
|
310
|
+
sig { params(source: T.any(Dependabot::Source, String), msg: T.nilable(String)).void }
|
78
311
|
def initialize(source, msg = nil)
|
79
312
|
@source = source
|
80
313
|
super(msg)
|
@@ -85,9 +318,50 @@ module Dependabot
|
|
85
318
|
# File level errors #
|
86
319
|
#####################
|
87
320
|
|
321
|
+
class MisconfiguredTooling < DependabotError
|
322
|
+
extend T::Sig
|
323
|
+
|
324
|
+
sig { returns(String) }
|
325
|
+
attr_reader :tool_name
|
326
|
+
|
327
|
+
sig { returns(String) }
|
328
|
+
attr_reader :tool_message
|
329
|
+
|
330
|
+
sig do
|
331
|
+
params(
|
332
|
+
tool_name: String,
|
333
|
+
tool_message: String
|
334
|
+
).void
|
335
|
+
end
|
336
|
+
def initialize(tool_name, tool_message)
|
337
|
+
@tool_name = tool_name
|
338
|
+
@tool_message = tool_message
|
339
|
+
|
340
|
+
msg = "Dependabot detected that #{tool_name} is misconfigured in this repository. " \
|
341
|
+
"Running `#{tool_name.downcase}` results in the following error: #{tool_message}"
|
342
|
+
super(msg)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
88
346
|
class ToolVersionNotSupported < DependabotError
|
89
|
-
|
347
|
+
extend T::Sig
|
348
|
+
|
349
|
+
sig { returns(String) }
|
350
|
+
attr_reader :tool_name
|
90
351
|
|
352
|
+
sig { returns(String) }
|
353
|
+
attr_reader :detected_version
|
354
|
+
|
355
|
+
sig { returns(String) }
|
356
|
+
attr_reader :supported_versions
|
357
|
+
|
358
|
+
sig do
|
359
|
+
params(
|
360
|
+
tool_name: String,
|
361
|
+
detected_version: String,
|
362
|
+
supported_versions: String
|
363
|
+
).void
|
364
|
+
end
|
91
365
|
def initialize(tool_name, detected_version, supported_versions)
|
92
366
|
@tool_name = tool_name
|
93
367
|
@detected_version = detected_version
|
@@ -100,6 +374,9 @@ module Dependabot
|
|
100
374
|
end
|
101
375
|
|
102
376
|
class DependencyFileNotFound < DependabotError
|
377
|
+
extend T::Sig
|
378
|
+
|
379
|
+
sig { returns(String) }
|
103
380
|
attr_reader :file_path
|
104
381
|
|
105
382
|
def initialize(file_path, msg = nil)
|
@@ -107,31 +384,39 @@ module Dependabot
|
|
107
384
|
super(msg || "#{file_path} not found")
|
108
385
|
end
|
109
386
|
|
387
|
+
sig { returns(String) }
|
110
388
|
def file_name
|
111
|
-
file_path.split("/").last
|
389
|
+
T.must(file_path.split("/").last)
|
112
390
|
end
|
113
391
|
|
392
|
+
sig { returns(String) }
|
114
393
|
def directory
|
115
394
|
# Directory should always start with a `/`
|
116
|
-
file_path.split("/")[0..-2].join("/").sub(%r{^/*}, "/")
|
395
|
+
T.must(file_path.split("/")[0..-2]).join("/").sub(%r{^/*}, "/")
|
117
396
|
end
|
118
397
|
end
|
119
398
|
|
120
399
|
class DependencyFileNotParseable < DependabotError
|
400
|
+
extend T::Sig
|
401
|
+
|
402
|
+
sig { returns(String) }
|
121
403
|
attr_reader :file_path
|
122
404
|
|
405
|
+
sig { params(file_path: String, msg: T.nilable(String)).void }
|
123
406
|
def initialize(file_path, msg = nil)
|
124
407
|
@file_path = file_path
|
125
408
|
super(msg || "#{file_path} not parseable")
|
126
409
|
end
|
127
410
|
|
411
|
+
sig { returns(String) }
|
128
412
|
def file_name
|
129
|
-
file_path.split("/").last
|
413
|
+
T.must(file_path.split("/").last)
|
130
414
|
end
|
131
415
|
|
416
|
+
sig { returns(String) }
|
132
417
|
def directory
|
133
418
|
# Directory should always start with a `/`
|
134
|
-
file_path.split("/")[0..-2].join("/").sub(%r{^/*}, "/")
|
419
|
+
T.must(file_path.split("/")[0..-2]).join("/").sub(%r{^/*}, "/")
|
135
420
|
end
|
136
421
|
end
|
137
422
|
|
@@ -144,10 +429,13 @@ module Dependabot
|
|
144
429
|
#######################
|
145
430
|
|
146
431
|
class PrivateSourceAuthenticationFailure < DependabotError
|
432
|
+
extend T::Sig
|
433
|
+
|
434
|
+
sig { returns(String) }
|
147
435
|
attr_reader :source
|
148
436
|
|
149
437
|
def initialize(source)
|
150
|
-
@source = sanitize_source(source)
|
438
|
+
@source = T.let(sanitize_source(source), String)
|
151
439
|
msg = "The following source could not be reached as it requires " \
|
152
440
|
"authentication (and any provided details were invalid or lacked " \
|
153
441
|
"the required permissions): #{@source}"
|
@@ -156,26 +444,38 @@ module Dependabot
|
|
156
444
|
end
|
157
445
|
|
158
446
|
class PrivateSourceTimedOut < DependabotError
|
447
|
+
extend T::Sig
|
448
|
+
|
449
|
+
sig { returns(String) }
|
159
450
|
attr_reader :source
|
160
451
|
|
452
|
+
sig { params(source: String).void }
|
161
453
|
def initialize(source)
|
162
|
-
@source = sanitize_source(source)
|
454
|
+
@source = T.let(sanitize_source(source), String)
|
163
455
|
super("The following source timed out: #{@source}")
|
164
456
|
end
|
165
457
|
end
|
166
458
|
|
167
459
|
class PrivateSourceCertificateFailure < DependabotError
|
460
|
+
extend T::Sig
|
461
|
+
|
462
|
+
sig { returns(String) }
|
168
463
|
attr_reader :source
|
169
464
|
|
465
|
+
sig { params(source: String).void }
|
170
466
|
def initialize(source)
|
171
|
-
@source = sanitize_source(source)
|
467
|
+
@source = T.let(sanitize_source(source), String)
|
172
468
|
super("Could not verify the SSL certificate for #{@source}")
|
173
469
|
end
|
174
470
|
end
|
175
471
|
|
176
472
|
class MissingEnvironmentVariable < DependabotError
|
473
|
+
extend T::Sig
|
474
|
+
|
475
|
+
sig { returns(String) }
|
177
476
|
attr_reader :environment_variable
|
178
477
|
|
478
|
+
sig { params(environment_variable: String).void }
|
179
479
|
def initialize(environment_variable)
|
180
480
|
@environment_variable = environment_variable
|
181
481
|
super("Missing environment variable #{@environment_variable}")
|
@@ -191,11 +491,15 @@ module Dependabot
|
|
191
491
|
###########################
|
192
492
|
|
193
493
|
class GitDependenciesNotReachable < DependabotError
|
494
|
+
extend T::Sig
|
495
|
+
|
496
|
+
sig { returns(T::Array[String]) }
|
194
497
|
attr_reader :dependency_urls
|
195
498
|
|
499
|
+
sig { params(dependency_urls: T.any(String, T::Array[String])).void }
|
196
500
|
def initialize(*dependency_urls)
|
197
501
|
@dependency_urls =
|
198
|
-
dependency_urls.flatten.map { |uri| filter_sensitive_data(uri) }
|
502
|
+
T.let(dependency_urls.flatten.map { |uri| filter_sensitive_data(uri) }, T::Array[String])
|
199
503
|
|
200
504
|
msg = "The following git URLs could not be retrieved: " \
|
201
505
|
"#{@dependency_urls.join(', ')}"
|
@@ -204,8 +508,12 @@ module Dependabot
|
|
204
508
|
end
|
205
509
|
|
206
510
|
class GitDependencyReferenceNotFound < DependabotError
|
511
|
+
extend T::Sig
|
512
|
+
|
513
|
+
sig { returns(String) }
|
207
514
|
attr_reader :dependency
|
208
515
|
|
516
|
+
sig { params(dependency: String).void }
|
209
517
|
def initialize(dependency)
|
210
518
|
@dependency = dependency
|
211
519
|
|
@@ -216,10 +524,14 @@ module Dependabot
|
|
216
524
|
end
|
217
525
|
|
218
526
|
class PathDependenciesNotReachable < DependabotError
|
527
|
+
extend T::Sig
|
528
|
+
|
529
|
+
sig { returns(T::Array[String]) }
|
219
530
|
attr_reader :dependencies
|
220
531
|
|
532
|
+
sig { params(dependencies: T.any(String, T::Array[String])).void }
|
221
533
|
def initialize(*dependencies)
|
222
|
-
@dependencies = dependencies.flatten
|
534
|
+
@dependencies = T.let(dependencies.flatten, T::Array[String])
|
223
535
|
msg = "The following path based dependencies could not be retrieved: " \
|
224
536
|
"#{@dependencies.join(', ')}"
|
225
537
|
super(msg)
|
@@ -227,8 +539,18 @@ module Dependabot
|
|
227
539
|
end
|
228
540
|
|
229
541
|
class GoModulePathMismatch < DependabotError
|
230
|
-
|
542
|
+
extend T::Sig
|
543
|
+
|
544
|
+
sig { returns(String) }
|
545
|
+
attr_reader :go_mod
|
546
|
+
|
547
|
+
sig { returns(String) }
|
548
|
+
attr_reader :declared_path
|
549
|
+
|
550
|
+
sig { returns(String) }
|
551
|
+
attr_reader :discovered_path
|
231
552
|
|
553
|
+
sig { params(go_mod: String, declared_path: String, discovered_path: String).void }
|
232
554
|
def initialize(go_mod, declared_path, discovered_path)
|
233
555
|
@go_mod = go_mod
|
234
556
|
@declared_path = declared_path
|