dependabot-cargo 0.319.1 → 0.320.1
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c970491f011f9d963496257c42f28afe724134ff190e6624a1a4f811b6ddab12
|
4
|
+
data.tar.gz: cefe48ec5bed87ebc31c4dde569f739448060ad975fd0161810b705cbfafcf49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ae5ed33b6aba59cad7f948c9f5b7f9154566516f39e4cc5338fcb38d22852369cb7964ea090542fdb420980b5597b19be77cd70ec59bb4db998cc62bd3ad419
|
7
|
+
data.tar.gz: 489b23fc468b4997093d4d7e4adabb1af961f82de82c05f029e5cc103c7b7d6d0e779aef2a45cb9e0ed122c6a1a49941eac1e9fae1f034229d22a24abc11234b
|
@@ -1,6 +1,7 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
4
5
|
require "toml-rb"
|
5
6
|
require "open3"
|
6
7
|
require "dependabot/git_commit_checker"
|
@@ -12,22 +13,39 @@ require "dependabot/shared_helpers"
|
|
12
13
|
module Dependabot
|
13
14
|
module Cargo
|
14
15
|
class FileUpdater
|
16
|
+
# rubocop:disable Metrics/ClassLength
|
15
17
|
class LockfileUpdater
|
18
|
+
extend T::Sig
|
16
19
|
LOCKFILE_ENTRY_REGEX = /
|
17
20
|
\[\[package\]\]\n
|
18
|
-
(?:(?!^\[(
|
21
|
+
(?:(?!^\[(?:\[package|metadata)).)+
|
19
22
|
/mx
|
20
23
|
|
21
24
|
LOCKFILE_CHECKSUM_REGEX = /^"checksum .*$/
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
sig do
|
27
|
+
params(
|
28
|
+
dependencies: T::Array[Dependabot::Dependency],
|
29
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
30
|
+
credentials: T::Array[Dependabot::Credential]
|
31
|
+
).void
|
27
32
|
end
|
28
|
-
|
33
|
+
def initialize(dependencies:, dependency_files:, credentials:)
|
34
|
+
@dependencies = T.let(dependencies, T::Array[Dependabot::Dependency])
|
35
|
+
@dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
|
36
|
+
@credentials = T.let(credentials, T::Array[Dependabot::Credential])
|
37
|
+
@custom_specification = T.let(nil, T.nilable(String))
|
38
|
+
@git_ssh_requirements_to_swap = T.let(nil, T.nilable(T::Hash[String, String]))
|
39
|
+
@manifest_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
40
|
+
@path_dependency_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
41
|
+
@lockfile = T.let(nil, T.nilable(Dependabot::DependencyFile))
|
42
|
+
@toolchain = T.let(nil, T.nilable(Dependabot::DependencyFile))
|
43
|
+
@config = T.let(nil, T.nilable(Dependabot::DependencyFile))
|
44
|
+
end
|
45
|
+
|
46
|
+
sig { returns(T.any(String, T.noreturn)) }
|
29
47
|
def updated_lockfile_content
|
30
|
-
base_directory = dependency_files.first.directory
|
48
|
+
base_directory = T.must(dependency_files.first).directory
|
31
49
|
SharedHelpers.in_a_temporary_directory(base_directory) do
|
32
50
|
write_temporary_dependency_files
|
33
51
|
|
@@ -42,6 +60,18 @@ module Dependabot
|
|
42
60
|
|
43
61
|
next updated_lockfile if updated_lockfile.include?(desired_lockfile_content)
|
44
62
|
|
63
|
+
# If exact version match fails, accept any update
|
64
|
+
if dependency_updated?(updated_lockfile, dependency)
|
65
|
+
actual_version = extract_actual_version(updated_lockfile, dependency.name)
|
66
|
+
if actual_version && actual_version != dependency.version
|
67
|
+
Dependabot.logger.info(
|
68
|
+
"Cargo selected version #{actual_version} instead of #{dependency.version} for #{dependency.name} " \
|
69
|
+
"due to dependency constraints"
|
70
|
+
)
|
71
|
+
end
|
72
|
+
next updated_lockfile
|
73
|
+
end
|
74
|
+
|
45
75
|
raise "Failed to update #{dependency.name}!"
|
46
76
|
end
|
47
77
|
rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
|
@@ -51,15 +81,22 @@ module Dependabot
|
|
51
81
|
|
52
82
|
private
|
53
83
|
|
84
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
54
85
|
attr_reader :dependencies
|
86
|
+
|
87
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
55
88
|
attr_reader :dependency_files
|
89
|
+
|
90
|
+
sig { returns(T::Array[T.untyped]) }
|
56
91
|
attr_reader :credentials
|
57
92
|
|
58
93
|
# Currently, there will only be a single updated dependency
|
94
|
+
sig { returns(Dependabot::Dependency) }
|
59
95
|
def dependency
|
60
|
-
dependencies.first
|
96
|
+
T.must(dependencies.first)
|
61
97
|
end
|
62
98
|
|
99
|
+
sig { params(error: StandardError).returns(T.noreturn) }
|
63
100
|
def handle_cargo_error(error)
|
64
101
|
raise unless error.message.include?("failed to select a version") ||
|
65
102
|
error.message.include?("no matching version") ||
|
@@ -72,6 +109,7 @@ module Dependabot
|
|
72
109
|
# rubocop:disable Metrics/PerceivedComplexity
|
73
110
|
# rubocop:disable Metrics/CyclomaticComplexity
|
74
111
|
# rubocop:disable Metrics/AbcSize
|
112
|
+
sig { params(error: StandardError).returns(T::Boolean) }
|
75
113
|
def better_specification_needed?(error)
|
76
114
|
return false if @custom_specification
|
77
115
|
return false unless error.message.match?(/specification .* is ambigu/)
|
@@ -85,16 +123,16 @@ module Dependabot
|
|
85
123
|
dependency.version
|
86
124
|
end
|
87
125
|
|
88
|
-
if spec_options.count { |s| s.end_with?(ver) } == 1
|
126
|
+
if ver && spec_options.count { |s| s.end_with?(ver) } == 1
|
89
127
|
@custom_specification = spec_options.find { |s| s.end_with?(ver) }
|
90
128
|
return true
|
91
|
-
elsif spec_options.count { |s| s.end_with?(ver) } > 1
|
129
|
+
elsif ver && spec_options.count { |s| s.end_with?(ver) } > 1
|
92
130
|
spec_options.select! { |s| s.end_with?(ver) }
|
93
131
|
end
|
94
132
|
|
95
133
|
if git_dependency? && git_source_url &&
|
96
|
-
spec_options.count { |s| s.include?(git_source_url) } >= 1
|
97
|
-
spec_options.select! { |s| s.include?(git_source_url) }
|
134
|
+
spec_options.count { |s| s.include?(T.must(git_source_url)) } >= 1
|
135
|
+
spec_options.select! { |s| s.include?(T.must(git_source_url)) }
|
98
136
|
end
|
99
137
|
|
100
138
|
@custom_specification = spec_options.first
|
@@ -104,6 +142,7 @@ module Dependabot
|
|
104
142
|
# rubocop:enable Metrics/CyclomaticComplexity
|
105
143
|
# rubocop:enable Metrics/PerceivedComplexity
|
106
144
|
|
145
|
+
sig { returns(String) }
|
107
146
|
def dependency_spec
|
108
147
|
return @custom_specification if @custom_specification
|
109
148
|
|
@@ -118,26 +157,30 @@ module Dependabot
|
|
118
157
|
spec
|
119
158
|
end
|
120
159
|
|
160
|
+
sig { returns(T.nilable(String)) }
|
121
161
|
def git_previous_version
|
122
162
|
TomlRB.parse(lockfile.content)
|
123
163
|
.fetch("package", [])
|
124
164
|
.select { |p| p["name"] == dependency.name }
|
125
165
|
.find { |p| p["source"].end_with?(dependency.previous_version) }
|
126
|
-
|
166
|
+
&.fetch("version")
|
127
167
|
end
|
128
168
|
|
169
|
+
sig { returns(T.nilable(String)) }
|
129
170
|
def git_source_url
|
130
171
|
dependency.previous_requirements
|
131
|
-
|
172
|
+
&.find { |r| r.dig(:source, :type) == "git" }
|
132
173
|
&.dig(:source, :url)
|
133
174
|
end
|
134
175
|
|
176
|
+
sig { returns(String) }
|
135
177
|
def desired_lockfile_content
|
136
|
-
return dependency.version if git_dependency?
|
178
|
+
return T.must(dependency.version) if git_dependency?
|
137
179
|
|
138
180
|
%(name = "#{dependency.name}"\nversion = "#{dependency.version}")
|
139
181
|
end
|
140
182
|
|
183
|
+
sig { params(command: String, fingerprint: String).void }
|
141
184
|
def run_cargo_command(command, fingerprint:)
|
142
185
|
start = Time.now
|
143
186
|
command = SharedHelpers.escape_command(command)
|
@@ -176,6 +219,7 @@ module Dependabot
|
|
176
219
|
)
|
177
220
|
end
|
178
221
|
|
222
|
+
sig { params(message: String).returns(T::Boolean) }
|
179
223
|
def using_old_toolchain?(message)
|
180
224
|
return true if message.include?("usage of sparse registries requires `-Z sparse-registry`")
|
181
225
|
|
@@ -185,18 +229,20 @@ module Dependabot
|
|
185
229
|
version_class.new(version_log[:version]) < version_class.new("1.68")
|
186
230
|
end
|
187
231
|
|
232
|
+
sig { void }
|
188
233
|
def write_temporary_dependency_files
|
189
234
|
write_temporary_manifest_files
|
190
235
|
write_temporary_path_dependency_files
|
191
236
|
|
192
237
|
File.write(lockfile.name, lockfile.content)
|
193
|
-
File.write(toolchain.name, toolchain.content) if toolchain
|
238
|
+
File.write(T.must(toolchain).name, T.must(toolchain).content) if toolchain
|
194
239
|
return unless config
|
195
240
|
|
196
|
-
FileUtils.mkdir_p(File.dirname(config.name))
|
197
|
-
File.write(config.name, config.content)
|
241
|
+
FileUtils.mkdir_p(File.dirname(T.must(config).name))
|
242
|
+
File.write(T.must(config).name, T.must(config).content)
|
198
243
|
end
|
199
244
|
|
245
|
+
sig { void }
|
200
246
|
def write_temporary_manifest_files
|
201
247
|
manifest_files.each do |file|
|
202
248
|
path = file.name
|
@@ -214,6 +260,7 @@ module Dependabot
|
|
214
260
|
end
|
215
261
|
end
|
216
262
|
|
263
|
+
sig { void }
|
217
264
|
def write_temporary_path_dependency_files
|
218
265
|
path_dependency_files.each do |file|
|
219
266
|
path = file.name
|
@@ -227,6 +274,7 @@ module Dependabot
|
|
227
274
|
end
|
228
275
|
end
|
229
276
|
|
277
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
230
278
|
def prepared_manifest_content(file)
|
231
279
|
content = updated_manifest_content(file)
|
232
280
|
content = pin_version(content) unless git_dependency?
|
@@ -236,12 +284,14 @@ module Dependabot
|
|
236
284
|
content
|
237
285
|
end
|
238
286
|
|
287
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
239
288
|
def prepared_path_dependency_content(file)
|
240
|
-
content = file.content.dup
|
289
|
+
content = T.must(file.content).dup
|
241
290
|
content = replace_ssh_urls(content)
|
242
291
|
content
|
243
292
|
end
|
244
293
|
|
294
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
245
295
|
def updated_manifest_content(file)
|
246
296
|
ManifestUpdater.new(
|
247
297
|
dependencies: dependencies,
|
@@ -249,6 +299,7 @@ module Dependabot
|
|
249
299
|
).updated_manifest_content
|
250
300
|
end
|
251
301
|
|
302
|
+
sig { params(content: String).returns(String) }
|
252
303
|
def pin_version(content)
|
253
304
|
parsed_manifest = TomlRB.parse(content)
|
254
305
|
|
@@ -269,6 +320,7 @@ module Dependabot
|
|
269
320
|
TomlRB.dump(parsed_manifest)
|
270
321
|
end
|
271
322
|
|
323
|
+
sig { params(parsed_manifest: T::Hash[String, T.untyped]).void }
|
272
324
|
def pin_target_specific_dependencies!(parsed_manifest)
|
273
325
|
parsed_manifest.fetch("target", {}).each do |target, t_details|
|
274
326
|
Cargo::FileParser::DEPENDENCY_TYPES.each do |type|
|
@@ -288,6 +340,7 @@ module Dependabot
|
|
288
340
|
end
|
289
341
|
end
|
290
342
|
|
343
|
+
sig { params(content: String).returns(String) }
|
291
344
|
def replace_ssh_urls(content)
|
292
345
|
git_ssh_requirements_to_swap.each do |ssh_url, https_url|
|
293
346
|
content = content.gsub(ssh_url, https_url)
|
@@ -295,18 +348,21 @@ module Dependabot
|
|
295
348
|
content
|
296
349
|
end
|
297
350
|
|
351
|
+
sig { params(content: String).returns(String) }
|
298
352
|
def remove_binary_specifications(content)
|
299
353
|
parsed_manifest = TomlRB.parse(content)
|
300
354
|
parsed_manifest.delete("bin")
|
301
355
|
TomlRB.dump(parsed_manifest)
|
302
356
|
end
|
303
357
|
|
358
|
+
sig { params(content: String).returns(String) }
|
304
359
|
def remove_default_run_specification(content)
|
305
360
|
parsed_manifest = TomlRB.parse(content)
|
306
361
|
parsed_manifest["package"].delete("default-run") if parsed_manifest.dig("package", "default-run")
|
307
362
|
TomlRB.dump(parsed_manifest)
|
308
363
|
end
|
309
364
|
|
365
|
+
sig { params(content: String).returns(String) }
|
310
366
|
def post_process_lockfile(content)
|
311
367
|
git_ssh_requirements_to_swap.each do |ssh_url, https_url|
|
312
368
|
content = content.gsub(https_url, ssh_url)
|
@@ -316,6 +372,7 @@ module Dependabot
|
|
316
372
|
content
|
317
373
|
end
|
318
374
|
|
375
|
+
sig { returns(T::Hash[String, String]) }
|
319
376
|
def git_ssh_requirements_to_swap
|
320
377
|
return @git_ssh_requirements_to_swap if @git_ssh_requirements_to_swap
|
321
378
|
|
@@ -338,6 +395,7 @@ module Dependabot
|
|
338
395
|
@git_ssh_requirements_to_swap
|
339
396
|
end
|
340
397
|
|
398
|
+
sig { params(lockfile_content: String).returns(String) }
|
341
399
|
def remove_duplicate_lockfile_entries(lockfile_content)
|
342
400
|
# Loop through the lockfile entries looking for duplicates. Replace
|
343
401
|
# any that are found
|
@@ -368,10 +426,12 @@ module Dependabot
|
|
368
426
|
lockfile_content
|
369
427
|
end
|
370
428
|
|
429
|
+
sig { returns(String) }
|
371
430
|
def dummy_app_content
|
372
431
|
%{fn main() {\nprintln!("Hello, world!");\n}}
|
373
432
|
end
|
374
433
|
|
434
|
+
sig { returns(T::Boolean) }
|
375
435
|
def git_dependency?
|
376
436
|
GitCommitChecker.new(
|
377
437
|
dependency: dependency,
|
@@ -379,6 +439,7 @@ module Dependabot
|
|
379
439
|
).git_dependency?
|
380
440
|
end
|
381
441
|
|
442
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
382
443
|
def manifest_files
|
383
444
|
@manifest_files ||=
|
384
445
|
dependency_files
|
@@ -386,6 +447,7 @@ module Dependabot
|
|
386
447
|
.reject(&:support_file?)
|
387
448
|
end
|
388
449
|
|
450
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
389
451
|
def path_dependency_files
|
390
452
|
@path_dependency_files ||=
|
391
453
|
dependency_files
|
@@ -393,27 +455,77 @@ module Dependabot
|
|
393
455
|
.select(&:support_file?)
|
394
456
|
end
|
395
457
|
|
458
|
+
sig { returns(Dependabot::DependencyFile) }
|
396
459
|
def lockfile
|
397
460
|
@lockfile ||= dependency_files.find { |f| f.name == "Cargo.lock" }
|
461
|
+
T.must(@lockfile)
|
398
462
|
end
|
399
463
|
|
464
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
400
465
|
def toolchain
|
401
466
|
@toolchain ||=
|
402
467
|
dependency_files.find { |f| f.name == "rust-toolchain" }
|
403
468
|
end
|
404
469
|
|
470
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
405
471
|
def config
|
406
472
|
@config ||= dependency_files.find { |f| f.name == ".cargo/config.toml" }
|
407
473
|
end
|
408
474
|
|
475
|
+
sig { params(file: Dependabot::DependencyFile).returns(T::Boolean) }
|
409
476
|
def virtual_manifest?(file)
|
410
|
-
!file.content.include?("[package]")
|
477
|
+
!T.must(file.content).include?("[package]")
|
411
478
|
end
|
412
479
|
|
480
|
+
sig { returns(T.class_of(Gem::Version)) }
|
413
481
|
def version_class
|
414
482
|
dependency.version_class
|
415
483
|
end
|
484
|
+
|
485
|
+
sig { params(lockfile_content: String, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
486
|
+
def dependency_updated?(lockfile_content, dependency)
|
487
|
+
return false unless dependency.previous_version
|
488
|
+
|
489
|
+
# For multiple versions case, we need to check the specific entry
|
490
|
+
# that corresponds to our dependency (the one used by our package)
|
491
|
+
entries = T.let([], T::Array[String])
|
492
|
+
lockfile_content.scan(LOCKFILE_ENTRY_REGEX) do
|
493
|
+
entries << Regexp.last_match.to_s
|
494
|
+
end
|
495
|
+
entries.select! { |entry| entry.include?("name = \"#{dependency.name}\"") }
|
496
|
+
|
497
|
+
# Check if any entry has a version newer than the previous version
|
498
|
+
entries.any? do |entry|
|
499
|
+
version_match = entry.match(/version = "([^"]+)"/)
|
500
|
+
next false unless version_match
|
501
|
+
|
502
|
+
new_version = version_match[1]
|
503
|
+
# Only consider it updated if it's newer than the previous version
|
504
|
+
# and either matches our expected version or is at least newer than previous
|
505
|
+
dependency.version_class.new(new_version) > dependency.version_class.new(dependency.previous_version)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
sig { params(lockfile_content: String, dependency_name: String).returns(T.nilable(String)) }
|
510
|
+
def extract_actual_version(lockfile_content, dependency_name)
|
511
|
+
entries = T.let([], T::Array[String])
|
512
|
+
lockfile_content.scan(LOCKFILE_ENTRY_REGEX) do
|
513
|
+
entries << Regexp.last_match.to_s
|
514
|
+
end
|
515
|
+
entries.select! { |entry| entry.include?("name = \"#{dependency_name}\"") }
|
516
|
+
|
517
|
+
# Get the highest version from matching entries
|
518
|
+
versions = entries.filter_map do |entry|
|
519
|
+
version_match = entry.match(/version = "([^"]+)"/)
|
520
|
+
version_match&.captures&.first
|
521
|
+
end
|
522
|
+
|
523
|
+
return nil if versions.empty?
|
524
|
+
|
525
|
+
versions.max_by { |v| version_class.new(v) }
|
526
|
+
end
|
416
527
|
end
|
528
|
+
# rubocop:enable Metrics/ClassLength
|
417
529
|
end
|
418
530
|
end
|
419
531
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-cargo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.320.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.
|
18
|
+
version: 0.320.1
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 0.
|
25
|
+
version: 0.320.1
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: debug
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -265,7 +265,7 @@ licenses:
|
|
265
265
|
- MIT
|
266
266
|
metadata:
|
267
267
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
268
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
268
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.320.1
|
269
269
|
rdoc_options: []
|
270
270
|
require_paths:
|
271
271
|
- lib
|