dependabot-nuget 0.250.0 → 0.252.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/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 +127 -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 +16 -21
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +4 -19
- 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 +121 -67
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +27 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +117 -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 +59 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +380 -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/Update/UpdateWorkerTestBase.cs +12 -40
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +30 -0
- 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 +195 -152
- 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 +43 -11
- 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,225 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "sorbet-runtime"
|
5
|
-
|
6
|
-
require "dependabot/nuget/file_fetcher/import_paths_finder"
|
7
|
-
require "dependabot/nuget/file_parser"
|
8
|
-
|
9
|
-
# For docs, see:
|
10
|
-
# - https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties
|
11
|
-
# - https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build
|
12
|
-
module Dependabot
|
13
|
-
module Nuget
|
14
|
-
class FileParser
|
15
|
-
class PropertyValueFinder
|
16
|
-
extend T::Sig
|
17
|
-
|
18
|
-
PROPERTY_REGEX = /\$\((?<property>.*?)\)/
|
19
|
-
|
20
|
-
sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
|
21
|
-
def initialize(dependency_files:)
|
22
|
-
@dependency_files = dependency_files
|
23
|
-
end
|
24
|
-
|
25
|
-
sig do
|
26
|
-
params(property_name: String,
|
27
|
-
callsite_file: Dependabot::DependencyFile,
|
28
|
-
stack: T::Array[[String, String]])
|
29
|
-
.returns(T.nilable(T::Hash[T.untyped, T.untyped]))
|
30
|
-
end
|
31
|
-
def property_details(property_name:, callsite_file:, stack: [])
|
32
|
-
stack += [[property_name, callsite_file.name]]
|
33
|
-
return if property_name.include?("(")
|
34
|
-
|
35
|
-
node_details = deep_find_prop_node(
|
36
|
-
property: property_name,
|
37
|
-
file: callsite_file
|
38
|
-
)
|
39
|
-
|
40
|
-
node_details ||=
|
41
|
-
find_property_in_directory_build_targets(
|
42
|
-
property: property_name,
|
43
|
-
callsite_file: callsite_file
|
44
|
-
)
|
45
|
-
|
46
|
-
node_details ||=
|
47
|
-
find_property_in_directory_build_props(
|
48
|
-
property: property_name,
|
49
|
-
callsite_file: callsite_file
|
50
|
-
)
|
51
|
-
|
52
|
-
node_details ||=
|
53
|
-
find_property_in_directory_packages_props(
|
54
|
-
property: property_name,
|
55
|
-
callsite_file: callsite_file
|
56
|
-
)
|
57
|
-
|
58
|
-
node_details ||=
|
59
|
-
find_property_in_packages_props(property: property_name)
|
60
|
-
|
61
|
-
return unless node_details
|
62
|
-
return node_details unless PROPERTY_REGEX.match?(node_details[:value])
|
63
|
-
|
64
|
-
check_next_level_of_stack(node_details, stack)
|
65
|
-
end
|
66
|
-
|
67
|
-
sig do
|
68
|
-
params(node_details: T.untyped,
|
69
|
-
stack: T::Array[[String, String]])
|
70
|
-
.returns(T.nilable(T::Hash[T.untyped, T.untyped]))
|
71
|
-
end
|
72
|
-
def check_next_level_of_stack(node_details, stack)
|
73
|
-
property_name = node_details.fetch(:value)
|
74
|
-
.match(PROPERTY_REGEX)
|
75
|
-
.named_captures.fetch("property")
|
76
|
-
callsite_file = dependency_files
|
77
|
-
.find { |f| f.name == node_details.fetch(:file) }
|
78
|
-
return unless callsite_file
|
79
|
-
|
80
|
-
raise "Circular reference!" if stack.include?([property_name, callsite_file.name])
|
81
|
-
|
82
|
-
property_details(
|
83
|
-
property_name: property_name,
|
84
|
-
callsite_file: callsite_file,
|
85
|
-
stack: stack
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
92
|
-
attr_reader :dependency_files
|
93
|
-
|
94
|
-
sig do
|
95
|
-
params(property: String,
|
96
|
-
file: Dependabot::DependencyFile)
|
97
|
-
.returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
98
|
-
end
|
99
|
-
def deep_find_prop_node(property:, file:)
|
100
|
-
doc = Nokogiri::XML(file.content)
|
101
|
-
doc.remove_namespaces!
|
102
|
-
node = doc.at_xpath(property_xpath(property))
|
103
|
-
|
104
|
-
# If we found a value for the property, return it
|
105
|
-
return node_details(file: file, node: node, property: property) if node
|
106
|
-
|
107
|
-
# Otherwise, we need to look in an imported file
|
108
|
-
import_path_finder =
|
109
|
-
Nuget::FileFetcher::ImportPathsFinder
|
110
|
-
.new(project_file: file)
|
111
|
-
|
112
|
-
import_paths = [
|
113
|
-
*import_path_finder.import_paths,
|
114
|
-
*import_path_finder.project_reference_paths
|
115
|
-
]
|
116
|
-
|
117
|
-
file = import_paths
|
118
|
-
.filter_map { |p| dependency_files.find { |f| f.name == p } }
|
119
|
-
.find { |f| deep_find_prop_node(property: property, file: f) }
|
120
|
-
|
121
|
-
return unless file
|
122
|
-
|
123
|
-
deep_find_prop_node(property: property, file: file)
|
124
|
-
end
|
125
|
-
|
126
|
-
sig do
|
127
|
-
params(property: String, callsite_file: Dependabot::DependencyFile)
|
128
|
-
.returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
129
|
-
end
|
130
|
-
def find_property_in_directory_build_targets(property:, callsite_file:)
|
131
|
-
find_property_in_up_tree_files(property: property, callsite_file: callsite_file,
|
132
|
-
expected_file_name: "Directory.Build.targets")
|
133
|
-
end
|
134
|
-
|
135
|
-
sig do
|
136
|
-
params(property: String, callsite_file: Dependabot::DependencyFile)
|
137
|
-
.returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
138
|
-
end
|
139
|
-
def find_property_in_directory_build_props(property:, callsite_file:)
|
140
|
-
find_property_in_up_tree_files(property: property, callsite_file: callsite_file,
|
141
|
-
expected_file_name: "Directory.Build.props")
|
142
|
-
end
|
143
|
-
|
144
|
-
sig do
|
145
|
-
params(property: String, callsite_file: Dependabot::DependencyFile)
|
146
|
-
.returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
147
|
-
end
|
148
|
-
def find_property_in_directory_packages_props(property:, callsite_file:)
|
149
|
-
find_property_in_up_tree_files(property: property, callsite_file: callsite_file,
|
150
|
-
expected_file_name: "Directory.Packages.props")
|
151
|
-
end
|
152
|
-
|
153
|
-
sig { params(property: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
154
|
-
def find_property_in_packages_props(property:)
|
155
|
-
file = packages_props_file
|
156
|
-
return unless file
|
157
|
-
|
158
|
-
deep_find_prop_node(property: property, file: file)
|
159
|
-
end
|
160
|
-
|
161
|
-
sig do
|
162
|
-
params(property: String,
|
163
|
-
callsite_file: Dependabot::DependencyFile,
|
164
|
-
expected_file_name: String)
|
165
|
-
.returns(T.untyped)
|
166
|
-
end
|
167
|
-
def find_property_in_up_tree_files(property:, callsite_file:, expected_file_name:)
|
168
|
-
files = up_tree_files_for_project(callsite_file, expected_file_name)
|
169
|
-
return if files.empty?
|
170
|
-
|
171
|
-
# first file where we were able to find the node
|
172
|
-
files.reduce(T.let(nil, T.nilable(String))) do |acc, file|
|
173
|
-
acc || deep_find_prop_node(property: property, file: file)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
sig do
|
178
|
-
params(project_file: DependencyFile, expected_file_name: String).returns(T::Array[Dependabot::DependencyFile])
|
179
|
-
end
|
180
|
-
def up_tree_files_for_project(project_file, expected_file_name)
|
181
|
-
dir = File.dirname(project_file.name)
|
182
|
-
|
183
|
-
# Simulate MSBuild walking up the directory structure looking for a file
|
184
|
-
possible_paths = dir.split("/").map.with_index do |_, i|
|
185
|
-
base = dir.split("/").first(i + 1).join("/")
|
186
|
-
Pathname.new(base + "/#{expected_file_name}").cleanpath.to_path
|
187
|
-
end.reverse + [expected_file_name]
|
188
|
-
|
189
|
-
paths =
|
190
|
-
possible_paths.uniq
|
191
|
-
.select { |p| dependency_files.find { |f| f.name.casecmp(p)&.zero? } }
|
192
|
-
|
193
|
-
dependency_files.select { |f| paths.include?(f.name) }
|
194
|
-
end
|
195
|
-
|
196
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
197
|
-
def packages_props_file
|
198
|
-
dependency_files.find { |f| f.name.casecmp("Packages.props")&.zero? }
|
199
|
-
end
|
200
|
-
|
201
|
-
sig { params(property_name: String).returns(String) }
|
202
|
-
def property_xpath(property_name)
|
203
|
-
# only return properties that don't have a `Condition` attribute or the `Condition` attribute is checking for
|
204
|
-
# an empty string, e.g., Condition="$(SomeProperty) == ''"
|
205
|
-
%{/Project/PropertyGroup/#{property_name}[not(@Condition) or @Condition="$(#{property_name}) == ''"]}
|
206
|
-
end
|
207
|
-
|
208
|
-
sig do
|
209
|
-
params(file: DependencyFile,
|
210
|
-
node: Nokogiri::XML::Node,
|
211
|
-
property: String)
|
212
|
-
.returns(T::Hash[Symbol, T.untyped])
|
213
|
-
end
|
214
|
-
def node_details(file:, node:, property:)
|
215
|
-
{
|
216
|
-
file: file.name,
|
217
|
-
node: node,
|
218
|
-
value: node.content.strip,
|
219
|
-
root_property_name: property
|
220
|
-
}
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "nokogiri"
|
5
|
-
require "sorbet-runtime"
|
6
|
-
|
7
|
-
require "dependabot/dependency_file"
|
8
|
-
require "dependabot/nuget/file_updater"
|
9
|
-
require "dependabot/nuget/file_parser/property_value_finder"
|
10
|
-
|
11
|
-
module Dependabot
|
12
|
-
module Nuget
|
13
|
-
class FileUpdater
|
14
|
-
class PropertyValueUpdater
|
15
|
-
extend T::Sig
|
16
|
-
|
17
|
-
sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
|
18
|
-
def initialize(dependency_files:)
|
19
|
-
@dependency_files = dependency_files
|
20
|
-
end
|
21
|
-
|
22
|
-
sig do
|
23
|
-
params(property_name: String,
|
24
|
-
updated_value: String,
|
25
|
-
callsite_file: Dependabot::DependencyFile)
|
26
|
-
.returns(T::Array[Dependabot::DependencyFile])
|
27
|
-
end
|
28
|
-
def update_files_for_property_change(property_name:, updated_value:,
|
29
|
-
callsite_file:)
|
30
|
-
declaration_details =
|
31
|
-
property_value_finder.property_details(
|
32
|
-
property_name: property_name,
|
33
|
-
callsite_file: callsite_file
|
34
|
-
)
|
35
|
-
throw "Unable to locate property details" unless declaration_details
|
36
|
-
|
37
|
-
declaration_filename = declaration_details.fetch(:file)
|
38
|
-
declaration_file = dependency_files.find do |f|
|
39
|
-
declaration_filename == f.name
|
40
|
-
end
|
41
|
-
throw "Unable to locate declaration file" unless declaration_file
|
42
|
-
|
43
|
-
content = T.must(declaration_file.content)
|
44
|
-
node = declaration_details.fetch(:node)
|
45
|
-
|
46
|
-
updated_content = content.sub(
|
47
|
-
%r{(<#{Regexp.quote(node.name)}(?:\s[^>]*)?>)
|
48
|
-
\s*#{Regexp.quote(node.content)}\s*
|
49
|
-
</#{Regexp.quote(node.name)}>}xm,
|
50
|
-
'\1' + "#{updated_value}</#{node.name}>"
|
51
|
-
)
|
52
|
-
|
53
|
-
files = dependency_files.dup
|
54
|
-
file_index = T.must(files.index(declaration_file))
|
55
|
-
files[file_index] =
|
56
|
-
update_file(file: declaration_file, content: updated_content)
|
57
|
-
files
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
sig { returns(T::Array[DependencyFile]) }
|
63
|
-
attr_reader :dependency_files
|
64
|
-
|
65
|
-
sig { returns(FileParser::PropertyValueFinder) }
|
66
|
-
def property_value_finder
|
67
|
-
@property_value_finder ||=
|
68
|
-
T.let(FileParser::PropertyValueFinder
|
69
|
-
.new(dependency_files: dependency_files), T.nilable(FileParser::PropertyValueFinder))
|
70
|
-
end
|
71
|
-
|
72
|
-
sig { params(file: DependencyFile, content: String).returns(DependencyFile) }
|
73
|
-
def update_file(file:, content:)
|
74
|
-
updated_file = file.dup
|
75
|
-
updated_file.content = content
|
76
|
-
updated_file
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|