dependabot-nuget 0.272.0 → 0.273.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/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +4 -19
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +0 -51
- data/lib/dependabot/nuget/file_parser.rb +1 -4
- data/lib/dependabot/nuget/file_updater.rb +97 -84
- data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +6 -4
- data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +4 -78
- data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -1
- data/lib/dependabot/nuget/native_helpers.rb +10 -25
- data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +8 -17
- data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +10 -45
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +4 -4
- data/lib/dependabot/nuget/update_checker.rb +1 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e74194b3b13f1f629b109a0dd66cff5e6063f898a0574b0af4a47204e2eaffa1
|
4
|
+
data.tar.gz: bb02d23751f1c81d9f0eaafd1e9afb1c1fd3ae3f48a0b31f902c62446d431905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39c13b396b743cbda78796d1539e67d9d44b222a9ca16edbc79468f29afddd83648434f534feb5f61957be751ec1e5d06b6387ebd4bbcc1aaeb88a2049fee69a
|
7
|
+
data.tar.gz: 16e2fa90c7e2b9214f5b63d88d8591d17a74ccee2db0dd82b0439d07fcbdaa3483297cdd5611fc5fae440e6a2511d5f0d16890166acd1a5035ac375a209f950c
|
@@ -108,7 +108,6 @@ public partial class AnalyzeWorker
|
|
108
108
|
discovery,
|
109
109
|
dependenciesToUpdate,
|
110
110
|
updatedVersion,
|
111
|
-
dependencyInfo,
|
112
111
|
nugetContext,
|
113
112
|
_logger,
|
114
113
|
CancellationToken.None);
|
@@ -360,7 +359,6 @@ public partial class AnalyzeWorker
|
|
360
359
|
WorkspaceDiscoveryResult discovery,
|
361
360
|
ImmutableHashSet<string> packageIds,
|
362
361
|
NuGetVersion updatedVersion,
|
363
|
-
DependencyInfo dependencyInfo,
|
364
362
|
NuGetContext nugetContext,
|
365
363
|
Logger logger,
|
366
364
|
CancellationToken cancellationToken)
|
@@ -381,23 +379,10 @@ public partial class AnalyzeWorker
|
|
381
379
|
.Select(NuGetFramework.Parse)
|
382
380
|
.ToImmutableArray();
|
383
381
|
|
384
|
-
// When updating dependencies, we only need to consider top-level dependencies
|
385
|
-
var
|
386
|
-
.
|
387
|
-
|
388
|
-
if (string.Compare(d.Name, dependencyInfo.Name, StringComparison.OrdinalIgnoreCase) == 0 &&
|
389
|
-
dependencyInfo.IsVulnerable)
|
390
|
-
{
|
391
|
-
// if this dependency is one we're specifically updating _and_ if it's vulnerable, always update it
|
392
|
-
return true;
|
393
|
-
}
|
394
|
-
else
|
395
|
-
{
|
396
|
-
// otherwise only update if it's a top-level dependency
|
397
|
-
return !d.IsTransitive;
|
398
|
-
}
|
399
|
-
});
|
400
|
-
var projectDependencyNames = relevantDependencies
|
382
|
+
// When updating peer dependencies, we only need to consider top-level dependencies.
|
383
|
+
var projectDependencyNames = projectsWithDependency
|
384
|
+
.SelectMany(p => p.Dependencies)
|
385
|
+
.Where(d => !d.IsTransitive)
|
401
386
|
.Select(d => d.Name)
|
402
387
|
.ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);
|
403
388
|
|
@@ -347,57 +347,6 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
|
|
347
347
|
);
|
348
348
|
}
|
349
349
|
|
350
|
-
[Fact]
|
351
|
-
public async Task AnalyzeVulnerableTransitiveDependencies()
|
352
|
-
{
|
353
|
-
await TestAnalyzeAsync(
|
354
|
-
packages:
|
355
|
-
[
|
356
|
-
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Dependency", "1.0.0", "net8.0"),
|
357
|
-
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Dependency", "1.0.1", "net8.0"),
|
358
|
-
],
|
359
|
-
discovery: new()
|
360
|
-
{
|
361
|
-
Path = "/",
|
362
|
-
Projects = [
|
363
|
-
new()
|
364
|
-
{
|
365
|
-
FilePath = "project.csproj",
|
366
|
-
TargetFrameworks = ["net8.0"],
|
367
|
-
Dependencies = [
|
368
|
-
new("Some.Transitive.Dependency", "1.0.0", DependencyType.Unknown, TargetFrameworks: ["net8.0"], IsTransitive: true),
|
369
|
-
]
|
370
|
-
}
|
371
|
-
]
|
372
|
-
},
|
373
|
-
dependencyInfo: new()
|
374
|
-
{
|
375
|
-
Name = "Some.Transitive.Dependency",
|
376
|
-
Version = "1.0.0",
|
377
|
-
IsVulnerable = true,
|
378
|
-
IgnoredVersions = [],
|
379
|
-
Vulnerabilities = [
|
380
|
-
new()
|
381
|
-
{
|
382
|
-
DependencyName = "Some.Transitive.Dependency",
|
383
|
-
PackageManager = "nuget",
|
384
|
-
VulnerableVersions = [Requirement.Parse("<= 1.0.0")],
|
385
|
-
SafeVersions = [Requirement.Parse("= 1.0.1")],
|
386
|
-
}
|
387
|
-
]
|
388
|
-
},
|
389
|
-
expectedResult: new()
|
390
|
-
{
|
391
|
-
UpdatedVersion = "1.0.1",
|
392
|
-
CanUpdate = true,
|
393
|
-
VersionComesFromMultiDependencyProperty = false,
|
394
|
-
UpdatedDependencies = [
|
395
|
-
new("Some.Transitive.Dependency", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"]),
|
396
|
-
],
|
397
|
-
}
|
398
|
-
);
|
399
|
-
}
|
400
|
-
|
401
350
|
[Fact]
|
402
351
|
public async Task IgnoredVersionsCanHandleWildcardSpecification()
|
403
352
|
{
|
@@ -50,10 +50,7 @@ module Dependabot
|
|
50
50
|
# cache discovery results
|
51
51
|
NativeDiscoveryJsonReader.set_discovery_from_dependency_files(dependency_files: dependency_files,
|
52
52
|
discovery: discovery_json_reader)
|
53
|
-
|
54
|
-
dependency_set = discovery_json_reader.dependency_set(dependency_files: dependency_files,
|
55
|
-
top_level_only: true)
|
56
|
-
dependency_set.dependencies
|
53
|
+
discovery_json_reader.dependency_set.dependencies
|
57
54
|
end
|
58
55
|
|
59
56
|
T.must(self.class.file_dependency_cache[key])
|
@@ -16,16 +16,6 @@ module Dependabot
|
|
16
16
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
17
17
|
extend T::Sig
|
18
18
|
|
19
|
-
DependencyDetails = T.type_alias do
|
20
|
-
{
|
21
|
-
file: String,
|
22
|
-
name: String,
|
23
|
-
version: String,
|
24
|
-
previous_version: String,
|
25
|
-
is_transitive: T::Boolean
|
26
|
-
}
|
27
|
-
end
|
28
|
-
|
29
19
|
sig { override.returns(T::Array[Regexp]) }
|
30
20
|
def self.updated_files_regex
|
31
21
|
[
|
@@ -62,21 +52,9 @@ module Dependabot
|
|
62
52
|
def updated_dependency_files
|
63
53
|
base_dir = "/"
|
64
54
|
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
|
65
|
-
|
66
|
-
|
67
|
-
name = T.let(dep_details.fetch(:name), String)
|
68
|
-
version = T.let(dep_details.fetch(:version), String)
|
69
|
-
previous_version = T.let(dep_details.fetch(:previous_version), String)
|
70
|
-
is_transitive = T.let(dep_details.fetch(:is_transitive), T::Boolean)
|
71
|
-
NativeHelpers.run_nuget_updater_tool(repo_root: T.must(repo_contents_path),
|
72
|
-
proj_path: file,
|
73
|
-
dependency_name: name,
|
74
|
-
version: version,
|
75
|
-
previous_version: previous_version,
|
76
|
-
is_transitive: is_transitive,
|
77
|
-
credentials: credentials)
|
55
|
+
dependencies.each do |dependency|
|
56
|
+
try_update_projects(dependency) || try_update_json(dependency)
|
78
57
|
end
|
79
|
-
|
80
58
|
updated_files = dependency_files.filter_map do |f|
|
81
59
|
updated_content = File.read(dependency_file_path(f))
|
82
60
|
next if updated_content == f.content
|
@@ -96,69 +74,104 @@ module Dependabot
|
|
96
74
|
|
97
75
|
private
|
98
76
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
77
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
78
|
+
def try_update_projects(dependency)
|
79
|
+
update_ran = T.let(false, T::Boolean)
|
80
|
+
checked_files = Set.new
|
81
|
+
|
82
|
+
# run update for each project file
|
83
|
+
project_files.each do |project_file|
|
84
|
+
project_dependencies = project_dependencies(project_file)
|
85
|
+
proj_path = dependency_file_path(project_file)
|
86
|
+
|
87
|
+
next unless project_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }
|
88
|
+
|
89
|
+
next unless repo_contents_path
|
90
|
+
|
91
|
+
checked_key = "#{project_file.name}-#{dependency.name}#{dependency.version}"
|
92
|
+
call_nuget_updater_tool(dependency, proj_path) unless checked_files.include?(checked_key)
|
93
|
+
|
94
|
+
checked_files.add(checked_key)
|
95
|
+
# We need to check the downstream references even though we're already evaluated the file
|
96
|
+
downstream_files = referenced_project_paths(project_file)
|
97
|
+
downstream_files.each do |downstream_file|
|
98
|
+
checked_files.add("#{downstream_file}-#{dependency.name}#{dependency.version}")
|
113
99
|
end
|
100
|
+
update_ran = true
|
101
|
+
end
|
102
|
+
update_ran
|
103
|
+
end
|
104
|
+
|
105
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
106
|
+
def try_update_json(dependency)
|
107
|
+
if dotnet_tools_json_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) } ||
|
108
|
+
global_json_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }
|
109
|
+
|
110
|
+
# We just need to feed the updater a project file, grab the first
|
111
|
+
project_file = T.must(project_files.first)
|
112
|
+
proj_path = dependency_file_path(project_file)
|
113
|
+
|
114
|
+
return false unless repo_contents_path
|
115
|
+
|
116
|
+
call_nuget_updater_tool(dependency, proj_path)
|
117
|
+
return true
|
118
|
+
end
|
114
119
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
120
|
+
false
|
121
|
+
end
|
122
|
+
|
123
|
+
sig { params(dependency: Dependency, proj_path: String).void }
|
124
|
+
def call_nuget_updater_tool(dependency, proj_path)
|
125
|
+
NativeHelpers.run_nuget_updater_tool(repo_root: T.must(repo_contents_path), proj_path: proj_path,
|
126
|
+
dependency: dependency, is_transitive: !dependency.top_level?,
|
127
|
+
credentials: credentials)
|
128
|
+
|
129
|
+
# Tests need to track how many times we call the tooling updater to ensure we don't recurse needlessly
|
130
|
+
# Ideally we should find a way to not run this code in prod
|
131
|
+
# (or a better way to track calls made to NativeHelpers)
|
132
|
+
@update_tooling_calls ||= T.let({}, T.nilable(T::Hash[String, Integer]))
|
133
|
+
key = "#{proj_path.delete_prefix(T.must(repo_contents_path))}+#{dependency.name}"
|
134
|
+
@update_tooling_calls[key] =
|
135
|
+
if @update_tooling_calls[key]
|
136
|
+
T.must(@update_tooling_calls[key]) + 1
|
137
|
+
else
|
138
|
+
1
|
131
139
|
end
|
132
|
-
|
133
|
-
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
140
|
+
end
|
141
|
+
|
142
|
+
# Don't call this from outside tests, we're only checking that we aren't recursing needlessly
|
143
|
+
sig { returns(T.nilable(T::Hash[String, Integer])) }
|
144
|
+
def testonly_update_tooling_calls
|
145
|
+
@update_tooling_calls
|
146
|
+
end
|
147
|
+
|
148
|
+
sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
|
149
|
+
def workspace
|
150
|
+
discovery_json_reader = NativeDiscoveryJsonReader.get_discovery_from_dependency_files(dependency_files)
|
151
|
+
discovery_json_reader.workspace_discovery
|
152
|
+
end
|
153
|
+
|
154
|
+
sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[String]) }
|
155
|
+
def referenced_project_paths(project_file)
|
156
|
+
workspace&.projects&.find { |p| p.file_path == project_file.name }&.referenced_project_paths || []
|
157
|
+
end
|
158
|
+
|
159
|
+
sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[NativeDependencyDetails]) }
|
160
|
+
def project_dependencies(project_file)
|
161
|
+
workspace&.projects&.find do |p|
|
162
|
+
full_project_file_path = File.join(project_file.directory, project_file.name)
|
163
|
+
p.file_path == full_project_file_path
|
164
|
+
end&.dependencies || []
|
165
|
+
end
|
166
|
+
|
167
|
+
sig { returns(T::Array[NativeDependencyDetails]) }
|
168
|
+
def global_json_dependencies
|
169
|
+
workspace&.global_json&.dependencies || []
|
170
|
+
end
|
171
|
+
|
172
|
+
sig { returns(T::Array[NativeDependencyDetails]) }
|
173
|
+
def dotnet_tools_json_dependencies
|
174
|
+
workspace&.dotnet_tools_json&.dependencies || []
|
162
175
|
end
|
163
176
|
|
164
177
|
# rubocop:disable Metrics/PerceivedComplexity
|
@@ -106,20 +106,22 @@ module Dependabot
|
|
106
106
|
.returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
107
107
|
end
|
108
108
|
def build_requirement(file_name, dependency_details)
|
109
|
+
return if dependency_details.is_transitive
|
110
|
+
|
109
111
|
version = dependency_details.version
|
110
112
|
version = nil if version&.empty?
|
111
|
-
metadata = { is_transitive: dependency_details.is_transitive }
|
112
113
|
|
113
114
|
requirement = {
|
114
115
|
requirement: version,
|
115
116
|
file: file_name,
|
116
117
|
groups: [dependency_details.is_dev_dependency ? "devDependencies" : "dependencies"],
|
117
|
-
source: nil
|
118
|
-
metadata: metadata
|
118
|
+
source: nil
|
119
119
|
}
|
120
120
|
|
121
121
|
property_name = dependency_details.evaluation&.root_property_name
|
122
|
-
|
122
|
+
return requirement unless property_name
|
123
|
+
|
124
|
+
requirement[:metadata] = { property_name: property_name }
|
123
125
|
requirement
|
124
126
|
end
|
125
127
|
end
|
@@ -125,90 +125,16 @@ module Dependabot
|
|
125
125
|
sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
|
126
126
|
attr_reader :workspace_discovery
|
127
127
|
|
128
|
+
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
129
|
+
attr_reader :dependency_set
|
130
|
+
|
128
131
|
sig { params(discovery_json: DependencyFile).void }
|
129
132
|
def initialize(discovery_json:)
|
130
133
|
@discovery_json = discovery_json
|
131
134
|
@workspace_discovery = T.let(read_workspace_discovery, T.nilable(Dependabot::Nuget::NativeWorkspaceDiscovery))
|
135
|
+
@dependency_set = T.let(read_dependency_set, Dependabot::FileParsers::Base::DependencySet)
|
132
136
|
end
|
133
137
|
|
134
|
-
# rubocop:disable Metrics/AbcSize
|
135
|
-
# rubocop:disable Metrics/MethodLength
|
136
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
137
|
-
sig do
|
138
|
-
params(
|
139
|
-
dependency_files: T::Array[Dependabot::DependencyFile],
|
140
|
-
top_level_only: T::Boolean
|
141
|
-
).returns(Dependabot::FileParsers::Base::DependencySet)
|
142
|
-
end
|
143
|
-
def dependency_set(dependency_files:, top_level_only:)
|
144
|
-
# dependencies must be recalculated so that we:
|
145
|
-
# 1. only return dependencies that are in the file set we reported earlier
|
146
|
-
# see https://github.com/dependabot/dependabot-core/issues/10303
|
147
|
-
# 2. the reported version is the minimum across all requirements; this ensures that we get the opportunity
|
148
|
-
# to update everything later
|
149
|
-
dependency_file_set = T.let(Set.new(dependency_files.map do |df|
|
150
|
-
Pathname.new(File.join(df.directory, df.name)).cleanpath.to_path
|
151
|
-
end), T::Set[String])
|
152
|
-
|
153
|
-
rebuilt_dependencies = read_dependency_set.dependencies.filter_map do |dep|
|
154
|
-
# only report requirements in files we know about
|
155
|
-
matching_requirements = dep.requirements.filter do |req|
|
156
|
-
file = T.let(req.fetch(:file), String)
|
157
|
-
dependency_file_set.include?(file)
|
158
|
-
end
|
159
|
-
|
160
|
-
# find the minimum version across all requirements
|
161
|
-
min_version = matching_requirements.filter_map do |req|
|
162
|
-
v = T.let(req.fetch(:requirement), T.nilable(String))
|
163
|
-
next unless v
|
164
|
-
|
165
|
-
Dependabot::Nuget::Version.new(v)
|
166
|
-
end.min
|
167
|
-
next unless min_version
|
168
|
-
|
169
|
-
# only return dependency requirements that are top-level
|
170
|
-
if top_level_only
|
171
|
-
matching_requirements.reject! do |req|
|
172
|
-
metadata = T.let(req.fetch(:metadata), T::Hash[Symbol, T.untyped])
|
173
|
-
T.let(metadata.fetch(:is_transitive), T::Boolean)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
# we might need to return a dependency like this
|
178
|
-
dep_without_reqs = Dependabot::Dependency.new(
|
179
|
-
name: dep.name,
|
180
|
-
version: min_version.to_s,
|
181
|
-
package_manager: "nuget",
|
182
|
-
requirements: []
|
183
|
-
)
|
184
|
-
|
185
|
-
dep_with_reqs = matching_requirements.filter_map do |req|
|
186
|
-
version = T.let(req.fetch(:requirement, nil), T.nilable(String))
|
187
|
-
next unless version
|
188
|
-
|
189
|
-
Dependabot::Dependency.new(
|
190
|
-
name: dep.name,
|
191
|
-
version: min_version.to_s,
|
192
|
-
package_manager: "nuget",
|
193
|
-
requirements: [req]
|
194
|
-
)
|
195
|
-
end
|
196
|
-
|
197
|
-
# if only returning top-level dependencies and we had no non-transitive requirements, return an empty
|
198
|
-
# dependency so it can be tracked for security updates
|
199
|
-
matching_requirements.empty? && top_level_only ? [dep_without_reqs] : dep_with_reqs
|
200
|
-
end.flatten
|
201
|
-
|
202
|
-
final_dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
203
|
-
rebuilt_dependencies.each do |dep|
|
204
|
-
final_dependency_set << dep
|
205
|
-
end
|
206
|
-
final_dependency_set
|
207
|
-
end
|
208
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
209
|
-
# rubocop:enable Metrics/MethodLength
|
210
|
-
# rubocop:enable Metrics/AbcSize
|
211
|
-
|
212
138
|
private
|
213
139
|
|
214
140
|
sig { returns(DependencyFile) }
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "dependabot/file_parsers/base/dependency_set"
|
5
4
|
require "dependabot/nuget/native_discovery/native_dependency_details"
|
6
5
|
require "dependabot/nuget/native_discovery/native_property_details"
|
7
6
|
require "sorbet-runtime"
|
@@ -171,18 +171,10 @@ module Dependabot
|
|
171
171
|
|
172
172
|
# rubocop:disable Metrics/MethodLength
|
173
173
|
sig do
|
174
|
-
params(
|
175
|
-
|
176
|
-
proj_path: String,
|
177
|
-
dependency_name: String,
|
178
|
-
version: String,
|
179
|
-
previous_version: String,
|
180
|
-
is_transitive: T::Boolean,
|
181
|
-
result_output_path: String
|
182
|
-
).returns([String, String])
|
174
|
+
params(repo_root: String, proj_path: String, dependency: Dependency,
|
175
|
+
is_transitive: T::Boolean, result_output_path: String).returns([String, String])
|
183
176
|
end
|
184
|
-
def self.get_nuget_updater_tool_command(repo_root:, proj_path:,
|
185
|
-
is_transitive:, result_output_path:)
|
177
|
+
def self.get_nuget_updater_tool_command(repo_root:, proj_path:, dependency:, is_transitive:, result_output_path:)
|
186
178
|
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
187
179
|
command_parts = [
|
188
180
|
exe_path,
|
@@ -192,11 +184,11 @@ module Dependabot
|
|
192
184
|
"--solution-or-project",
|
193
185
|
proj_path,
|
194
186
|
"--dependency",
|
195
|
-
|
187
|
+
dependency.name,
|
196
188
|
"--new-version",
|
197
|
-
version,
|
189
|
+
dependency.version,
|
198
190
|
"--previous-version",
|
199
|
-
previous_version,
|
191
|
+
dependency.previous_version,
|
200
192
|
is_transitive ? "--transitive" : nil,
|
201
193
|
"--result-output-path",
|
202
194
|
result_output_path,
|
@@ -237,21 +229,14 @@ module Dependabot
|
|
237
229
|
params(
|
238
230
|
repo_root: String,
|
239
231
|
proj_path: String,
|
240
|
-
|
241
|
-
version: String,
|
242
|
-
previous_version: String,
|
232
|
+
dependency: Dependency,
|
243
233
|
is_transitive: T::Boolean,
|
244
234
|
credentials: T::Array[Dependabot::Credential]
|
245
235
|
).void
|
246
236
|
end
|
247
|
-
def self.run_nuget_updater_tool(repo_root:, proj_path:,
|
248
|
-
|
249
|
-
|
250
|
-
proj_path: proj_path,
|
251
|
-
dependency_name: dependency_name,
|
252
|
-
version: version,
|
253
|
-
previous_version: previous_version,
|
254
|
-
is_transitive: is_transitive,
|
237
|
+
def self.run_nuget_updater_tool(repo_root:, proj_path:, dependency:, is_transitive:, credentials:)
|
238
|
+
(command, fingerprint) = get_nuget_updater_tool_command(repo_root: repo_root, proj_path: proj_path,
|
239
|
+
dependency: dependency, is_transitive: is_transitive,
|
255
240
|
result_output_path: update_result_file_path)
|
256
241
|
|
257
242
|
puts "running NuGet updater:\n" + command
|
@@ -21,18 +21,15 @@ module Dependabot
|
|
21
21
|
sig do
|
22
22
|
params(
|
23
23
|
requirements: T::Array[T::Hash[Symbol, T.untyped]],
|
24
|
-
dependency_details: T.nilable(Dependabot::Nuget::NativeDependencyDetails)
|
25
|
-
vulnerable: T::Boolean
|
24
|
+
dependency_details: T.nilable(Dependabot::Nuget::NativeDependencyDetails)
|
26
25
|
)
|
27
26
|
.void
|
28
27
|
end
|
29
|
-
def initialize(requirements:, dependency_details
|
28
|
+
def initialize(requirements:, dependency_details:)
|
30
29
|
@requirements = requirements
|
31
30
|
@dependency_details = dependency_details
|
32
|
-
@vulnerable = vulnerable
|
33
31
|
end
|
34
32
|
|
35
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
36
33
|
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
37
34
|
def updated_requirements
|
38
35
|
return requirements unless clean_version
|
@@ -40,18 +37,13 @@ module Dependabot
|
|
40
37
|
# NOTE: Order is important here. The FileUpdater needs the updated
|
41
38
|
# requirement at index `i` to correspond to the previous requirement
|
42
39
|
# at the same index.
|
43
|
-
requirements.
|
44
|
-
next if
|
45
|
-
|
46
|
-
previous_requirement = req.fetch(:requirement)
|
47
|
-
req[:metadata][:previous_requirement] = previous_requirement
|
48
|
-
|
49
|
-
next req if previous_requirement.nil?
|
50
|
-
next req if previous_requirement.include?(",")
|
40
|
+
requirements.map do |req|
|
41
|
+
next req if req.fetch(:requirement).nil?
|
42
|
+
next req if req.fetch(:requirement).include?(",")
|
51
43
|
|
52
44
|
new_req =
|
53
|
-
if
|
54
|
-
update_wildcard_requirement(
|
45
|
+
if req.fetch(:requirement).include?("*")
|
46
|
+
update_wildcard_requirement(req.fetch(:requirement))
|
55
47
|
else
|
56
48
|
# Since range requirements are excluded by the line above we can
|
57
49
|
# replace anything that looks like a version with the new
|
@@ -62,7 +54,7 @@ module Dependabot
|
|
62
54
|
)
|
63
55
|
end
|
64
56
|
|
65
|
-
next req if new_req ==
|
57
|
+
next req if new_req == req.fetch(:requirement)
|
66
58
|
|
67
59
|
new_source = req[:source]&.dup
|
68
60
|
unless @dependency_details.nil?
|
@@ -75,7 +67,6 @@ module Dependabot
|
|
75
67
|
req.merge({ requirement: new_req, source: new_source })
|
76
68
|
end
|
77
69
|
end
|
78
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
79
70
|
|
80
71
|
private
|
81
72
|
|
@@ -56,8 +56,7 @@ module Dependabot
|
|
56
56
|
dep_details = updated_dependency_details.find { |d| d.name.casecmp?(dependency.name) }
|
57
57
|
NativeRequirementsUpdater.new(
|
58
58
|
requirements: dependency.requirements,
|
59
|
-
dependency_details: dep_details
|
60
|
-
vulnerable: vulnerable?
|
59
|
+
dependency_details: dep_details
|
61
60
|
).updated_requirements
|
62
61
|
end
|
63
62
|
|
@@ -113,10 +112,9 @@ module Dependabot
|
|
113
112
|
|
114
113
|
sig { void }
|
115
114
|
def write_dependency_info
|
116
|
-
dependency_version = T.let(dependency.requirements.first&.fetch(:requirement, nil), T.nilable(String))
|
117
115
|
dependency_info = {
|
118
116
|
Name: dependency.name,
|
119
|
-
Version:
|
117
|
+
Version: dependency.version.to_s,
|
120
118
|
IsVulnerable: vulnerable?,
|
121
119
|
IgnoredVersions: ignored_versions,
|
122
120
|
Vulnerabilities: security_advisories.map do |vulnerability|
|
@@ -143,7 +141,7 @@ module Dependabot
|
|
143
141
|
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
144
142
|
def discovered_dependencies
|
145
143
|
discovery_json_reader = NativeDiscoveryJsonReader.get_discovery_from_dependency_files(dependency_files)
|
146
|
-
discovery_json_reader.dependency_set
|
144
|
+
discovery_json_reader.dependency_set
|
147
145
|
end
|
148
146
|
|
149
147
|
sig { override.returns(T::Boolean) }
|
@@ -152,10 +150,6 @@ module Dependabot
|
|
152
150
|
true
|
153
151
|
end
|
154
152
|
|
155
|
-
# rubocop:disable Metrics/AbcSize
|
156
|
-
# rubocop:disable Metrics/BlockLength
|
157
|
-
# rubocop:disable Metrics/MethodLength
|
158
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
159
153
|
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
160
154
|
def updated_dependencies_after_full_unlock
|
161
155
|
dependencies = discovered_dependencies.dependencies
|
@@ -163,16 +157,14 @@ module Dependabot
|
|
163
157
|
dep = dependencies.find { |d| d.name.casecmp(dependency_details.name)&.zero? }
|
164
158
|
next unless dep
|
165
159
|
|
166
|
-
|
160
|
+
metadata = {}
|
167
161
|
# For peer dependencies, instruct updater to not directly update this dependency
|
168
|
-
|
169
|
-
dep_metadata[:is_vulnerable] = vulnerable?
|
162
|
+
metadata = { information_only: true } unless dependency.name.casecmp(dependency_details.name)&.zero?
|
170
163
|
|
171
164
|
# rebuild the new requirements with the updated dependency details
|
172
165
|
updated_reqs = dep.requirements.map do |r|
|
173
166
|
r = r.clone
|
174
|
-
|
175
|
-
r[:requirement] = dependency_details.version # set new version
|
167
|
+
r[:requirement] = dependency_details.version
|
176
168
|
r[:source] = {
|
177
169
|
type: "nuget_repo",
|
178
170
|
source_url: dependency_details.info_url
|
@@ -180,44 +172,17 @@ module Dependabot
|
|
180
172
|
r
|
181
173
|
end
|
182
174
|
|
183
|
-
reqs = dep.requirements
|
184
|
-
unless vulnerable?
|
185
|
-
updated_reqs = updated_reqs.filter do |r|
|
186
|
-
req_metadata = T.let(r.fetch(:metadata, {}), T::Hash[Symbol, T.untyped])
|
187
|
-
!T.let(req_metadata[:is_transitive], T::Boolean)
|
188
|
-
end
|
189
|
-
reqs = reqs.filter do |r|
|
190
|
-
req_metadata = T.let(r.fetch(:metadata, {}), T::Hash[Symbol, T.untyped])
|
191
|
-
!T.let(req_metadata[:is_transitive], T::Boolean)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# report back the highest version that all of these dependencies can be updated to
|
196
|
-
# this will ensure that we get a chance to update all relevant dependencies
|
197
|
-
max_updatable_version = updated_reqs.filter_map do |r|
|
198
|
-
v = T.let(r.fetch(:requirement, nil), T.nilable(String))
|
199
|
-
next unless v
|
200
|
-
|
201
|
-
Dependabot::Nuget::Version.new(v)
|
202
|
-
end.max
|
203
|
-
next unless max_updatable_version
|
204
|
-
|
205
|
-
previous_version = T.let(dep.requirements.first&.fetch(:requirement, nil), T.nilable(String))
|
206
175
|
Dependency.new(
|
207
176
|
name: dep.name,
|
208
|
-
version:
|
177
|
+
version: dependency_details.version,
|
209
178
|
requirements: updated_reqs,
|
210
|
-
previous_version:
|
211
|
-
previous_requirements:
|
179
|
+
previous_version: dep.version,
|
180
|
+
previous_requirements: dep.requirements,
|
212
181
|
package_manager: dep.package_manager,
|
213
|
-
metadata:
|
182
|
+
metadata: metadata
|
214
183
|
)
|
215
184
|
end
|
216
185
|
end
|
217
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
218
|
-
# rubocop:enable Metrics/MethodLength
|
219
|
-
# rubocop:enable Metrics/BlockLength
|
220
|
-
# rubocop:enable Metrics/AbcSize
|
221
186
|
|
222
187
|
sig { returns(T::Array[Dependabot::Nuget::NativeDependencyDetails]) }
|
223
188
|
def updated_dependency_details
|
@@ -37,11 +37,10 @@ module Dependabot
|
|
37
37
|
def updated_requirements
|
38
38
|
return requirements unless latest_version
|
39
39
|
|
40
|
+
# NOTE: Order is important here. The FileUpdater needs the updated
|
41
|
+
# requirement at index `i` to correspond to the previous requirement
|
42
|
+
# at the same index.
|
40
43
|
requirements.map do |req|
|
41
|
-
req[:metadata] ||= {}
|
42
|
-
req[:metadata][:is_transitive] = false
|
43
|
-
req[:metadata][:previous_requirement] = req[:requirement]
|
44
|
-
|
45
44
|
next req if req.fetch(:requirement).nil?
|
46
45
|
next req if req.fetch(:requirement).include?(",")
|
47
46
|
|
@@ -57,6 +56,7 @@ module Dependabot
|
|
57
56
|
latest_version.to_s
|
58
57
|
)
|
59
58
|
end
|
59
|
+
|
60
60
|
next req if new_req == req.fetch(:requirement)
|
61
61
|
|
62
62
|
req.merge(requirement: new_req, source: updated_source)
|
@@ -166,8 +166,7 @@ module Dependabot
|
|
166
166
|
requirements: updated_requirements,
|
167
167
|
previous_version: dependency.version,
|
168
168
|
previous_requirements: dependency.requirements,
|
169
|
-
package_manager: dependency.package_manager
|
170
|
-
metadata: { is_vulnerable: vulnerable? }
|
169
|
+
package_manager: dependency.package_manager
|
171
170
|
)
|
172
171
|
updated_dependencies = [updated_dependency]
|
173
172
|
updated_dependencies += DependencyFinder.new(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-nuget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.273.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.273.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.273.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -463,7 +463,7 @@ licenses:
|
|
463
463
|
- MIT
|
464
464
|
metadata:
|
465
465
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
466
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
466
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.273.0
|
467
467
|
post_install_message:
|
468
468
|
rdoc_options: []
|
469
469
|
require_paths:
|