dependabot-nuget 0.251.0 → 0.253.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/Directory.Common.props +1 -0
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +26 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +35 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/NuGetUpdater.Cli.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +4 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +251 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +27 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/NuGetUpdater.Cli.Test.csproj +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Dependency.cs +56 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyType.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs +69 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscoveryResult.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +217 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +30 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscoveryResult.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +30 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscoveryResult.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/IDiscoveryResult.cs +14 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +29 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +128 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EvaluationResult.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EvaluationResultType.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/BuildFile.cs +6 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/DotNetToolsJsonBuildFile.cs +4 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +24 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/PackagesConfigBuildFile.cs +8 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +100 -19
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/XmlBuildFile.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +6 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Property.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +23 -36
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +59 -26
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +5 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/HashSetExtensions.cs +14 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ImmutableArrayExtensions.cs +18 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +281 -140
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +27 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +18 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +135 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +91 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +71 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +67 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +405 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +306 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +36 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/DotNetToolsJsonBuildFileTests.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +2 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/PackagesConfigBuildFileTests.cs +4 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/ProjectBuildFileTests.cs +6 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +4 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +38 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +1 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +13 -41
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +0 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +0 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +0 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +0 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +30 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +272 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/DiffUtil.cs +266 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +239 -161
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/SdkPackageUpdaterHelperTests.cs +7 -11
- data/lib/dependabot/nuget/discovery/dependency_details.rb +95 -0
- data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +126 -0
- data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +43 -0
- data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +83 -0
- data/lib/dependabot/nuget/discovery/evaluation_details.rb +63 -0
- data/lib/dependabot/nuget/discovery/project_discovery.rb +71 -0
- data/lib/dependabot/nuget/discovery/property_details.rb +43 -0
- data/lib/dependabot/nuget/discovery/workspace_discovery.rb +66 -0
- data/lib/dependabot/nuget/file_parser.rb +19 -128
- data/lib/dependabot/nuget/file_updater.rb +28 -60
- data/lib/dependabot/nuget/native_helpers.rb +55 -0
- data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +3 -8
- data/lib/dependabot/nuget/update_checker/dependency_finder.rb +1 -0
- data/lib/dependabot/nuget/update_checker/property_updater.rb +1 -0
- data/lib/dependabot/nuget/update_checker/tfm_finder.rb +17 -152
- data/lib/dependabot/nuget/update_checker/version_finder.rb +1 -6
- data/lib/dependabot/nuget/update_checker.rb +4 -1
- metadata +44 -25
- data/lib/dependabot/nuget/file_parser/dotnet_tools_json_parser.rb +0 -71
- data/lib/dependabot/nuget/file_parser/global_json_parser.rb +0 -68
- data/lib/dependabot/nuget/file_parser/packages_config_parser.rb +0 -92
- data/lib/dependabot/nuget/file_parser/project_file_parser.rb +0 -620
- data/lib/dependabot/nuget/file_parser/property_value_finder.rb +0 -225
- data/lib/dependabot/nuget/file_updater/property_value_updater.rb +0 -81
@@ -1,11 +1,11 @@
|
|
1
1
|
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "nokogiri"
|
5
|
-
|
6
4
|
require "dependabot/dependency"
|
7
5
|
require "dependabot/file_parsers"
|
8
6
|
require "dependabot/file_parsers/base"
|
7
|
+
require "dependabot/nuget/discovery/discovery_json_reader"
|
8
|
+
require "dependabot/nuget/native_helpers"
|
9
9
|
require "sorbet-runtime"
|
10
10
|
|
11
11
|
# For details on how dotnet handles version constraints, see:
|
@@ -16,106 +16,31 @@ module Dependabot
|
|
16
16
|
extend T::Sig
|
17
17
|
|
18
18
|
require "dependabot/file_parsers/base/dependency_set"
|
19
|
-
require_relative "file_parser/project_file_parser"
|
20
|
-
require_relative "file_parser/packages_config_parser"
|
21
|
-
require_relative "file_parser/global_json_parser"
|
22
|
-
require_relative "file_parser/dotnet_tools_json_parser"
|
23
|
-
|
24
|
-
PACKAGE_CONF_DEPENDENCY_SELECTOR = "packages > packages"
|
25
19
|
|
26
20
|
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
27
21
|
def parse
|
28
|
-
|
29
|
-
|
30
|
-
dependency_set += packages_config_dependencies
|
31
|
-
dependency_set += global_json_dependencies if global_json
|
32
|
-
dependency_set += dotnet_tools_json_dependencies if dotnet_tools_json
|
33
|
-
|
34
|
-
(dependencies, deps_with_unresolved_versions) = dependency_set.dependencies.partition do |d|
|
35
|
-
# try to parse the version; don't care about result, just that it succeeded
|
36
|
-
_ = Version.new(d.version)
|
37
|
-
true
|
38
|
-
rescue ArgumentError
|
39
|
-
# version could not be parsed
|
40
|
-
false
|
41
|
-
end
|
22
|
+
workspace_path = project_files.first&.directory
|
23
|
+
return [] unless workspace_path
|
42
24
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
requirements_info = d.requirements.filter_map { |r| " file: #{r[:file]}, metadata: #{r[:metadata]}" }
|
49
|
-
.join("\n")
|
50
|
-
" name: #{d.name}, version: #{d.version}\n#{requirements_info}"
|
51
|
-
end.join("\n")
|
25
|
+
# run discovery for the repo
|
26
|
+
NativeHelpers.run_nuget_discover_tool(repo_root: T.must(repo_contents_path),
|
27
|
+
workspace_path: workspace_path,
|
28
|
+
output_path: DiscoveryJsonReader.discovery_file_path,
|
29
|
+
credentials: credentials)
|
52
30
|
|
53
|
-
|
54
|
-
Dependabot.logger.info "The following dependencies were found:\n#{dependency_info}"
|
55
|
-
end
|
56
|
-
|
57
|
-
dependencies
|
31
|
+
discovered_dependencies.dependencies
|
58
32
|
end
|
59
33
|
|
60
34
|
private
|
61
35
|
|
62
36
|
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
project_files.each do |project_file|
|
67
|
-
tfms = project_file_parser.target_frameworks(project_file: project_file)
|
68
|
-
unless tfms.any?
|
69
|
-
Dependabot.logger.warn "Excluding project file '#{project_file.name}' due to unresolvable target framework"
|
70
|
-
next
|
71
|
-
end
|
72
|
-
|
73
|
-
dependency_set += project_file_parser.dependency_set(project_file: project_file)
|
74
|
-
end
|
75
|
-
|
76
|
-
proj_files.each do |proj_file|
|
77
|
-
dependency_set += project_file_parser.dependency_set(project_file: proj_file)
|
78
|
-
end
|
79
|
-
|
80
|
-
dependency_set
|
81
|
-
end
|
82
|
-
|
83
|
-
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
84
|
-
def packages_config_dependencies
|
85
|
-
dependency_set = DependencySet.new
|
86
|
-
|
87
|
-
packages_config_files.each do |file|
|
88
|
-
parser = PackagesConfigParser.new(packages_config: file)
|
89
|
-
dependency_set += parser.dependency_set
|
90
|
-
end
|
91
|
-
|
92
|
-
dependency_set
|
93
|
-
end
|
94
|
-
|
95
|
-
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
96
|
-
def global_json_dependencies
|
97
|
-
return DependencySet.new unless global_json
|
37
|
+
def discovered_dependencies
|
38
|
+
discovery_json = DiscoveryJsonReader.discovery_json
|
39
|
+
return DependencySet.new unless discovery_json
|
98
40
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
103
|
-
def dotnet_tools_json_dependencies
|
104
|
-
return DependencySet.new unless dotnet_tools_json
|
105
|
-
|
106
|
-
DotNetToolsJsonParser.new(dotnet_tools_json: T.must(dotnet_tools_json)).dependency_set
|
107
|
-
end
|
108
|
-
|
109
|
-
sig { returns(Dependabot::Nuget::FileParser::ProjectFileParser) }
|
110
|
-
def project_file_parser
|
111
|
-
@project_file_parser ||= T.let(
|
112
|
-
ProjectFileParser.new(
|
113
|
-
dependency_files: dependency_files,
|
114
|
-
credentials: credentials,
|
115
|
-
repo_contents_path: @repo_contents_path
|
116
|
-
),
|
117
|
-
T.nilable(Dependabot::Nuget::FileParser::ProjectFileParser)
|
118
|
-
)
|
41
|
+
DiscoveryJsonReader.new(
|
42
|
+
discovery_json: discovery_json
|
43
|
+
).dependency_set
|
119
44
|
end
|
120
45
|
|
121
46
|
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
@@ -136,47 +61,13 @@ module Dependabot
|
|
136
61
|
end
|
137
62
|
end
|
138
63
|
|
139
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
140
|
-
def packages_config_files
|
141
|
-
dependency_files.select do |f|
|
142
|
-
f.name.split("/").last&.casecmp("packages.config")&.zero?
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
147
|
-
def project_import_files
|
148
|
-
dependency_files -
|
149
|
-
project_files -
|
150
|
-
packages_config_files -
|
151
|
-
nuget_configs -
|
152
|
-
[global_json] -
|
153
|
-
[dotnet_tools_json]
|
154
|
-
end
|
155
|
-
|
156
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
157
|
-
def nuget_configs
|
158
|
-
dependency_files.select { |f| f.name.match?(/nuget\.config$/i) }
|
159
|
-
end
|
160
|
-
|
161
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
162
|
-
def global_json
|
163
|
-
dependency_files.find { |f| f.name.casecmp?("global.json") }
|
164
|
-
end
|
165
|
-
|
166
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
167
|
-
def dotnet_tools_json
|
168
|
-
dependency_files.find { |f| f.name.casecmp?(".config/dotnet-tools.json") }
|
169
|
-
end
|
170
|
-
|
171
64
|
sig { override.void }
|
172
65
|
def check_required_files
|
173
|
-
if project_files.any? || proj_files.any?
|
174
|
-
return
|
175
|
-
end
|
66
|
+
return if project_files.any? || proj_files.any?
|
176
67
|
|
177
68
|
raise Dependabot::DependencyFileNotFound.new(
|
178
|
-
"*.(cs|vb|fs)proj, *.proj
|
179
|
-
"No project file
|
69
|
+
"*.(cs|vb|fs)proj, *.proj",
|
70
|
+
"No project file or *.proj!"
|
180
71
|
)
|
181
72
|
end
|
182
73
|
end
|
@@ -4,6 +4,9 @@
|
|
4
4
|
require "dependabot/dependency_file"
|
5
5
|
require "dependabot/file_updaters"
|
6
6
|
require "dependabot/file_updaters/base"
|
7
|
+
require "dependabot/nuget/discovery/dependency_details"
|
8
|
+
require "dependabot/nuget/discovery/discovery_json_reader"
|
9
|
+
require "dependabot/nuget/discovery/workspace_discovery"
|
7
10
|
require "dependabot/nuget/native_helpers"
|
8
11
|
require "dependabot/shared_helpers"
|
9
12
|
require "sorbet-runtime"
|
@@ -13,11 +16,6 @@ module Dependabot
|
|
13
16
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
14
17
|
extend T::Sig
|
15
18
|
|
16
|
-
require_relative "file_updater/property_value_updater"
|
17
|
-
require_relative "file_parser/project_file_parser"
|
18
|
-
require_relative "file_parser/dotnet_tools_json_parser"
|
19
|
-
require_relative "file_parser/packages_config_parser"
|
20
|
-
|
21
19
|
sig { override.returns(T::Array[Regexp]) }
|
22
20
|
def self.updated_files_regex
|
23
21
|
[
|
@@ -67,7 +65,7 @@ module Dependabot
|
|
67
65
|
project_dependencies = project_dependencies(project_file)
|
68
66
|
proj_path = dependency_file_path(project_file)
|
69
67
|
|
70
|
-
next unless project_dependencies.any? { |dep| dep.name.casecmp(dependency.name)
|
68
|
+
next unless project_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }
|
71
69
|
|
72
70
|
next unless repo_contents_path
|
73
71
|
|
@@ -76,7 +74,7 @@ module Dependabot
|
|
76
74
|
|
77
75
|
checked_files.add(checked_key)
|
78
76
|
# We need to check the downstream references even though we're already evaluated the file
|
79
|
-
downstream_files =
|
77
|
+
downstream_files = referenced_project_paths(project_file)
|
80
78
|
downstream_files.each do |downstream_file|
|
81
79
|
checked_files.add("#{downstream_file}-#{dependency.name}#{dependency.version}")
|
82
80
|
end
|
@@ -87,8 +85,8 @@ module Dependabot
|
|
87
85
|
|
88
86
|
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
89
87
|
def try_update_json(dependency)
|
90
|
-
if dotnet_tools_json_dependencies.any? { |dep| dep.name.casecmp(dependency.name)
|
91
|
-
global_json_dependencies.any? { |dep| dep.name.casecmp(dependency.name)
|
88
|
+
if dotnet_tools_json_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) } ||
|
89
|
+
global_json_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }
|
92
90
|
|
93
91
|
# We just need to feed the updater a project file, grab the first
|
94
92
|
project_file = T.must(project_files.first)
|
@@ -128,58 +126,38 @@ module Dependabot
|
|
128
126
|
@update_tooling_calls
|
129
127
|
end
|
130
128
|
|
131
|
-
sig {
|
132
|
-
def
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
sig { returns(T.nilable(WorkspaceDiscovery)) }
|
130
|
+
def workspace
|
131
|
+
@workspace ||= T.let(begin
|
132
|
+
discovery_json = DiscoveryJsonReader.discovery_json
|
133
|
+
if discovery_json
|
134
|
+
workspace = DiscoveryJsonReader.new(
|
135
|
+
discovery_json: discovery_json
|
136
|
+
).workspace_discovery
|
137
|
+
end
|
137
138
|
|
138
|
-
|
139
|
-
|
139
|
+
workspace
|
140
|
+
end, T.nilable(WorkspaceDiscovery))
|
140
141
|
end
|
141
142
|
|
142
|
-
sig { params(project_file: Dependabot::DependencyFile).returns(T
|
143
|
-
def
|
144
|
-
|
145
|
-
packages_config_path = project_file.name.gsub(project_file_name, "packages.config")
|
146
|
-
packages_config_files.find { |f| f.name == packages_config_path }
|
143
|
+
sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[String]) }
|
144
|
+
def referenced_project_paths(project_file)
|
145
|
+
workspace&.projects&.find { |p| p.file_path == project_file.name }&.referenced_project_paths || []
|
147
146
|
end
|
148
147
|
|
149
|
-
sig {
|
150
|
-
def
|
151
|
-
|
152
|
-
T.let(
|
153
|
-
FileParser::ProjectFileParser.new(
|
154
|
-
dependency_files: dependency_files,
|
155
|
-
credentials: credentials,
|
156
|
-
repo_contents_path: repo_contents_path
|
157
|
-
),
|
158
|
-
T.nilable(Dependabot::Nuget::FileParser::ProjectFileParser)
|
159
|
-
)
|
148
|
+
sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[DependencyDetails]) }
|
149
|
+
def project_dependencies(project_file)
|
150
|
+
workspace&.projects&.find { |p| p.file_path == project_file.name }&.dependencies || []
|
160
151
|
end
|
161
152
|
|
162
|
-
sig { returns(T::Array[
|
153
|
+
sig { returns(T::Array[DependencyDetails]) }
|
163
154
|
def global_json_dependencies
|
164
|
-
|
165
|
-
|
166
|
-
@global_json_dependencies ||=
|
167
|
-
T.let(
|
168
|
-
FileParser::GlobalJsonParser.new(global_json: T.must(global_json)).dependency_set.dependencies,
|
169
|
-
T.nilable(T::Array[Dependabot::Dependency])
|
170
|
-
)
|
155
|
+
workspace&.global_json&.dependencies || []
|
171
156
|
end
|
172
157
|
|
173
|
-
sig { returns(T::Array[
|
158
|
+
sig { returns(T::Array[DependencyDetails]) }
|
174
159
|
def dotnet_tools_json_dependencies
|
175
|
-
|
176
|
-
|
177
|
-
@dotnet_tools_json_dependencies ||=
|
178
|
-
T.let(
|
179
|
-
FileParser::DotNetToolsJsonParser.new(dotnet_tools_json: T.must(dotnet_tools_json))
|
180
|
-
.dependency_set.dependencies,
|
181
|
-
T.nilable(T::Array[Dependabot::Dependency])
|
182
|
-
)
|
160
|
+
workspace&.dotnet_tools_json&.dependencies || []
|
183
161
|
end
|
184
162
|
|
185
163
|
# rubocop:disable Metrics/PerceivedComplexity
|
@@ -234,16 +212,6 @@ module Dependabot
|
|
234
212
|
end
|
235
213
|
end
|
236
214
|
|
237
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
238
|
-
def global_json
|
239
|
-
dependency_files.find { |f| T.must(f.name.casecmp("global.json")).zero? }
|
240
|
-
end
|
241
|
-
|
242
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
243
|
-
def dotnet_tools_json
|
244
|
-
dependency_files.find { |f| T.must(f.name.casecmp(".config/dotnet-tools.json")).zero? }
|
245
|
-
end
|
246
|
-
|
247
215
|
sig { override.void }
|
248
216
|
def check_required_files
|
249
217
|
return if project_files.any? || packages_config_files.any?
|
@@ -55,6 +55,61 @@ module Dependabot
|
|
55
55
|
false
|
56
56
|
end
|
57
57
|
|
58
|
+
sig do
|
59
|
+
params(repo_root: String, workspace_path: String, output_path: String).returns([String, String])
|
60
|
+
end
|
61
|
+
def self.get_nuget_discover_tool_command(repo_root:, workspace_path:, output_path:)
|
62
|
+
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
63
|
+
command_parts = [
|
64
|
+
exe_path,
|
65
|
+
"discover",
|
66
|
+
"--repo-root",
|
67
|
+
repo_root,
|
68
|
+
"--workspace",
|
69
|
+
workspace_path,
|
70
|
+
"--output",
|
71
|
+
output_path,
|
72
|
+
"--verbose"
|
73
|
+
].compact
|
74
|
+
|
75
|
+
command = Shellwords.join(command_parts)
|
76
|
+
|
77
|
+
fingerprint = [
|
78
|
+
exe_path,
|
79
|
+
"discover",
|
80
|
+
"--repo-root",
|
81
|
+
"<repo-root>",
|
82
|
+
"--workspace",
|
83
|
+
"<path-to-workspace>",
|
84
|
+
"--output",
|
85
|
+
"<path-to-output>",
|
86
|
+
"--verbose"
|
87
|
+
].compact.join(" ")
|
88
|
+
|
89
|
+
[command, fingerprint]
|
90
|
+
end
|
91
|
+
|
92
|
+
sig do
|
93
|
+
params(
|
94
|
+
repo_root: String,
|
95
|
+
workspace_path: String,
|
96
|
+
output_path: String,
|
97
|
+
credentials: T::Array[Dependabot::Credential]
|
98
|
+
).void
|
99
|
+
end
|
100
|
+
def self.run_nuget_discover_tool(repo_root:, workspace_path:, output_path:, credentials:)
|
101
|
+
(command, fingerprint) = get_nuget_discover_tool_command(repo_root: repo_root,
|
102
|
+
workspace_path: workspace_path,
|
103
|
+
output_path: output_path)
|
104
|
+
|
105
|
+
puts "running NuGet discovery:\n" + command
|
106
|
+
|
107
|
+
NuGetConfigCredentialHelpers.patch_nuget_config_for_action(credentials) do
|
108
|
+
output = SharedHelpers.run_shell_command(command, allow_unsafe_shell_command: true, fingerprint: fingerprint)
|
109
|
+
puts output
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
58
113
|
sig do
|
59
114
|
params(repo_root: String, proj_path: String, dependency: Dependency,
|
60
115
|
is_transitive: T::Boolean).returns([String, String])
|
@@ -18,14 +18,12 @@ module Dependabot
|
|
18
18
|
sig do
|
19
19
|
params(
|
20
20
|
dependency_urls: T::Array[T::Hash[Symbol, String]],
|
21
|
-
dependency: Dependabot::Dependency
|
22
|
-
tfm_finder: Dependabot::Nuget::TfmFinder
|
21
|
+
dependency: Dependabot::Dependency
|
23
22
|
).void
|
24
23
|
end
|
25
|
-
def initialize(dependency_urls:, dependency
|
24
|
+
def initialize(dependency_urls:, dependency:)
|
26
25
|
@dependency_urls = dependency_urls
|
27
26
|
@dependency = dependency
|
28
|
-
@tfm_finder = tfm_finder
|
29
27
|
end
|
30
28
|
|
31
29
|
sig { params(version: String).returns(T::Boolean) }
|
@@ -57,9 +55,6 @@ module Dependabot
|
|
57
55
|
sig { returns(Dependabot::Dependency) }
|
58
56
|
attr_reader :dependency
|
59
57
|
|
60
|
-
sig { returns(Dependabot::Nuget::TfmFinder) }
|
61
|
-
attr_reader :tfm_finder
|
62
|
-
|
63
58
|
sig { params(nuspec_xml: Nokogiri::XML::Document).returns(T::Boolean) }
|
64
59
|
def pure_development_dependency?(nuspec_xml)
|
65
60
|
contents = nuspec_xml.at_xpath("package/metadata/developmentDependency")&.content&.strip
|
@@ -82,7 +77,7 @@ module Dependabot
|
|
82
77
|
|
83
78
|
sig { returns(T.nilable(T::Array[String])) }
|
84
79
|
def project_tfms
|
85
|
-
@project_tfms ||= T.let(
|
80
|
+
@project_tfms ||= T.let(TfmFinder.frameworks(dependency), T.nilable(T::Array[String]))
|
86
81
|
end
|
87
82
|
|
88
83
|
sig { params(dependency_version: String).returns(T.nilable(T::Array[String])) }
|
@@ -1,164 +1,29 @@
|
|
1
1
|
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "
|
5
|
-
require "nokogiri"
|
6
|
-
require "sorbet-runtime"
|
7
|
-
|
8
|
-
require "dependabot/update_checkers/base"
|
9
|
-
require "dependabot/nuget/version"
|
10
|
-
require "dependabot/nuget/requirement"
|
11
|
-
require "dependabot/nuget/native_helpers"
|
12
|
-
require "dependabot/shared_helpers"
|
4
|
+
require "dependabot/nuget/discovery/discovery_json_reader"
|
13
5
|
|
14
6
|
module Dependabot
|
15
7
|
module Nuget
|
16
8
|
class TfmFinder
|
17
9
|
extend T::Sig
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
sig { params(dependency: Dependabot::Dependency).returns(T::Array[String]) }
|
36
|
-
def frameworks(dependency)
|
37
|
-
tfms = Set.new
|
38
|
-
tfms += project_file_tfms(dependency)
|
39
|
-
tfms += project_import_file_tfms
|
40
|
-
tfms.to_a
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
46
|
-
attr_reader :dependency_files
|
47
|
-
|
48
|
-
sig { returns(T::Array[Dependabot::Credential]) }
|
49
|
-
attr_reader :credentials
|
50
|
-
|
51
|
-
sig { returns(T.nilable(String)) }
|
52
|
-
attr_reader :repo_contents_path
|
53
|
-
|
54
|
-
sig { params(dependency: Dependabot::Dependency).returns(T::Array[String]) }
|
55
|
-
def project_file_tfms(dependency)
|
56
|
-
project_files_with_dependency(dependency).flat_map do |file|
|
57
|
-
project_file_parser.target_frameworks(project_file: file)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
sig { params(dependency: Dependabot::Dependency).returns(T::Array[Dependabot::DependencyFile]) }
|
62
|
-
def project_files_with_dependency(dependency)
|
63
|
-
project_files.select do |file|
|
64
|
-
packages_config_contains_dependency?(file, dependency) ||
|
65
|
-
project_file_contains_dependency?(file, dependency)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
70
|
-
def packages_config_contains_dependency?(file, dependency)
|
71
|
-
config_file = find_packages_config_file(file)
|
72
|
-
return false unless config_file
|
73
|
-
|
74
|
-
config_parser = FileParser::PackagesConfigParser.new(packages_config: config_file)
|
75
|
-
config_parser.dependency_set.dependencies.any? do |d|
|
76
|
-
d.name.casecmp(dependency.name)&.zero?
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
81
|
-
def project_file_contains_dependency?(file, dependency)
|
82
|
-
project_file_parser.dependency_set(project_file: file).dependencies.any? do |d|
|
83
|
-
d.name.casecmp(dependency.name)&.zero?
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
sig { params(file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::DependencyFile)) }
|
88
|
-
def find_packages_config_file(file)
|
89
|
-
return file if file.name.end_with?("packages.config")
|
90
|
-
|
91
|
-
filename = File.basename(file.name)
|
92
|
-
search_path = file.name.sub(filename, "packages.config")
|
93
|
-
|
94
|
-
dependency_files.find { |f| f.name.casecmp(search_path)&.zero? }
|
95
|
-
end
|
96
|
-
|
97
|
-
sig { returns(T::Array[String]) }
|
98
|
-
def project_import_file_tfms
|
99
|
-
@project_import_file_tfms ||=
|
100
|
-
T.let(
|
101
|
-
project_import_files.flat_map do |file|
|
102
|
-
project_file_parser.target_frameworks(project_file: file)
|
103
|
-
end,
|
104
|
-
T.nilable(T::Array[String])
|
105
|
-
)
|
106
|
-
end
|
107
|
-
|
108
|
-
sig { returns(FileParser::ProjectFileParser) }
|
109
|
-
def project_file_parser
|
110
|
-
@project_file_parser ||=
|
111
|
-
T.let(
|
112
|
-
FileParser::ProjectFileParser.new(
|
113
|
-
dependency_files: dependency_files,
|
114
|
-
credentials: credentials,
|
115
|
-
repo_contents_path: repo_contents_path
|
116
|
-
),
|
117
|
-
T.nilable(FileParser::ProjectFileParser)
|
118
|
-
)
|
119
|
-
end
|
120
|
-
|
121
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
122
|
-
def project_files
|
123
|
-
projfile = /\.[a-z]{2}proj$/
|
124
|
-
packageprops = /[Dd]irectory.[Pp]ackages.props/
|
125
|
-
|
126
|
-
dependency_files.select do |df|
|
127
|
-
df.name.match?(projfile) ||
|
128
|
-
df.name.match?(packageprops)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
133
|
-
def packages_config_files
|
134
|
-
dependency_files.select do |f|
|
135
|
-
f.name.split("/").last&.casecmp("packages.config")&.zero?
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
140
|
-
def project_import_files
|
141
|
-
dependency_files -
|
142
|
-
project_files -
|
143
|
-
packages_config_files -
|
144
|
-
nuget_configs -
|
145
|
-
[global_json] -
|
146
|
-
[dotnet_tools_json]
|
147
|
-
end
|
148
|
-
|
149
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
150
|
-
def nuget_configs
|
151
|
-
dependency_files.select { |f| f.name.match?(/nuget\.config$/i) }
|
152
|
-
end
|
153
|
-
|
154
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
155
|
-
def global_json
|
156
|
-
dependency_files.find { |f| f.name.casecmp("global.json")&.zero? }
|
157
|
-
end
|
158
|
-
|
159
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
160
|
-
def dotnet_tools_json
|
161
|
-
dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json")&.zero? }
|
11
|
+
sig { params(dependency: Dependency).returns(T::Array[String]) }
|
12
|
+
def self.frameworks(dependency)
|
13
|
+
discovery_json = DiscoveryJsonReader.discovery_json
|
14
|
+
return [] unless discovery_json
|
15
|
+
|
16
|
+
workspace = DiscoveryJsonReader.new(
|
17
|
+
discovery_json: discovery_json
|
18
|
+
).workspace_discovery
|
19
|
+
return [] unless workspace
|
20
|
+
|
21
|
+
workspace.projects.select do |project|
|
22
|
+
all_dependencies = project.dependencies + project.referenced_project_paths.flat_map do |ref|
|
23
|
+
workspace.projects.find { |p| p.file_path == ref }&.dependencies || []
|
24
|
+
end
|
25
|
+
all_dependencies.any? { |d| d.name.casecmp?(dependency.name) }
|
26
|
+
end.flat_map(&:target_frameworks).uniq
|
162
27
|
end
|
163
28
|
end
|
164
29
|
end
|
@@ -160,12 +160,7 @@ module Dependabot
|
|
160
160
|
T.let(
|
161
161
|
CompatibilityChecker.new(
|
162
162
|
dependency_urls: dependency_urls,
|
163
|
-
dependency: dependency
|
164
|
-
tfm_finder: TfmFinder.new(
|
165
|
-
dependency_files: dependency_files,
|
166
|
-
credentials: credentials,
|
167
|
-
repo_contents_path: repo_contents_path
|
168
|
-
)
|
163
|
+
dependency: dependency
|
169
164
|
),
|
170
165
|
T.nilable(Dependabot::Nuget::CompatibilityChecker)
|
171
166
|
)
|
@@ -16,6 +16,8 @@ module Dependabot
|
|
16
16
|
require_relative "update_checker/requirements_updater"
|
17
17
|
require_relative "update_checker/dependency_finder"
|
18
18
|
|
19
|
+
PROPERTY_REGEX = /\$\((?<property>.*?)\)/
|
20
|
+
|
19
21
|
sig { override.returns(T.nilable(String)) }
|
20
22
|
def latest_version
|
21
23
|
# No need to find latest version for transitive dependencies unless they have a vulnerability.
|
@@ -81,7 +83,7 @@ module Dependabot
|
|
81
83
|
# that property couldn't be found, and the requirement therefore
|
82
84
|
# cannot be unlocked (since we can't update that property)
|
83
85
|
dependency.requirements.none? do |req|
|
84
|
-
req.fetch(:requirement)&.match?(
|
86
|
+
req.fetch(:requirement)&.match?(PROPERTY_REGEX)
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
@@ -219,6 +221,7 @@ module Dependabot
|
|
219
221
|
T.let(
|
220
222
|
Nuget::FileParser.new(
|
221
223
|
dependency_files: dependency_files,
|
224
|
+
repo_contents_path: repo_contents_path,
|
222
225
|
source: nil
|
223
226
|
).parse.select do |dep|
|
224
227
|
dep.requirements.any? { |req| req.dig(:metadata, :property_name) }
|