dependabot-nuget 0.289.0 → 0.290.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +26 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +2 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +3 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -9
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +17 -0
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +24 -4
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +2 -1
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +13 -12
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +2 -2
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +0 -4
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +7 -31
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +340 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +0 -12
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +55 -0
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -6
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +557 -713
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +2 -2
  43. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +1 -1
  44. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  45. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  46. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  47. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  48. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  49. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  50. data/lib/dependabot/nuget/file_fetcher.rb +2 -3
  51. data/lib/dependabot/nuget/file_parser.rb +2 -3
  52. data/lib/dependabot/nuget/file_updater.rb +13 -13
  53. data/lib/dependabot/nuget/native_helpers.rb +14 -5
  54. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  55. data/lib/dependabot/nuget/update_checker.rb +116 -190
  56. metadata +18 -29
  57. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  58. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  59. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  60. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -122
  61. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -277
  62. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  63. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -104
  64. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  65. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -61
  66. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  67. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -214
  68. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  69. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  70. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  71. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  72. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  73. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  74. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  75. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  76. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  77. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -1,277 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/dependency"
5
- require "dependabot/file_parsers/base/dependency_set"
6
- require "dependabot/nuget/cache_manager"
7
- require "dependabot/nuget/native_discovery/native_workspace_discovery"
8
- require "json"
9
- require "sorbet-runtime"
10
-
11
- module Dependabot
12
- module Nuget
13
- class NativeDiscoveryJsonReader
14
- extend T::Sig
15
-
16
- sig { returns(T::Hash[String, NativeDiscoveryJsonReader]) }
17
- def self.cache_directory_to_discovery_json_reader
18
- CacheManager.cache("cache_directory_to_discovery_json_reader")
19
- end
20
-
21
- sig { returns(T::Hash[String, NativeDiscoveryJsonReader]) }
22
- def self.cache_dependency_file_paths_to_discovery_json_reader
23
- CacheManager.cache("cache_dependency_file_paths_to_discovery_json_reader")
24
- end
25
-
26
- sig { returns(T::Hash[String, String]) }
27
- def self.cache_dependency_file_paths_to_discovery_json_path
28
- CacheManager.cache("cache_dependency_file_paths_to_discovery_json_path")
29
- end
30
-
31
- sig { void }
32
- def self.testonly_clear_caches
33
- cache_directory_to_discovery_json_reader.clear
34
- cache_dependency_file_paths_to_discovery_json_reader.clear
35
- cache_dependency_file_paths_to_discovery_json_path.clear
36
- end
37
-
38
- sig { void }
39
- def self.testonly_clear_discovery_files
40
- # this will get recreated when necessary
41
- FileUtils.rm_rf(discovery_directory)
42
- end
43
-
44
- sig { params(error_if_missing: T::Boolean).void }
45
- def self.debug_report_discovery_files(error_if_missing:)
46
- if File.exist?(discovery_map_file_path)
47
- Dependabot.logger.info("Discovery map file (#{discovery_map_file_path}) contents: " \
48
- "#{File.read(discovery_map_file_path)}")
49
- Dependabot.logger.info("Discovery files: #{Dir.glob(File.join(discovery_directory, '*'))}")
50
- elsif error_if_missing
51
- Dependabot.logger.error("discovery map file missing")
52
- end
53
- end
54
-
55
- # Runs NuGet dependency discovery in the given directory and returns a new instance of NativeDiscoveryJsonReader.
56
- # The location of the resultant JSON file is saved.
57
- sig do
58
- params(
59
- repo_contents_path: String,
60
- directory: String,
61
- credentials: T::Array[Dependabot::Credential]
62
- ).returns(NativeDiscoveryJsonReader)
63
- end
64
- def self.run_discovery_in_directory(repo_contents_path:, directory:, credentials:)
65
- # run discovery
66
- job_file_path = ENV.fetch("DEPENDABOT_JOB_PATH")
67
- discovery_json_path = discovery_file_path_from_workspace_path(directory)
68
- unless File.exist?(discovery_json_path)
69
- NativeHelpers.run_nuget_discover_tool(job_path: job_file_path,
70
- repo_root: repo_contents_path,
71
- workspace_path: directory,
72
- output_path: discovery_json_path,
73
- credentials: credentials)
74
-
75
- Dependabot.logger.info("Discovery JSON content: #{File.read(discovery_json_path)}")
76
- end
77
- load_discovery_for_directory(repo_contents_path: repo_contents_path, directory: directory)
78
- end
79
-
80
- # Loads NuGet dependency discovery for the given directory and returns a new instance of
81
- # NativeDiscoveryJsonReader and caches the resultant object.
82
- sig { params(repo_contents_path: String, directory: String).returns(NativeDiscoveryJsonReader) }
83
- def self.load_discovery_for_directory(repo_contents_path:, directory:)
84
- cache_directory_to_discovery_json_reader[directory] ||= begin
85
- discovery_json_reader = discovery_json_reader(repo_contents_path: repo_contents_path,
86
- workspace_path: directory)
87
- cache_directory_to_discovery_json_reader[directory] = discovery_json_reader
88
- dependency_file_cache_key = cache_key_from_dependency_file_paths(discovery_json_reader.dependency_file_paths)
89
- cache_dependency_file_paths_to_discovery_json_reader[dependency_file_cache_key] = discovery_json_reader
90
- discovery_file_path = discovery_file_path_from_workspace_path(directory)
91
- cache_dependency_file_paths_to_discovery_json_path[dependency_file_cache_key] = discovery_file_path
92
-
93
- discovery_json_reader
94
- end
95
- end
96
-
97
- # Retrieves the cached NativeDiscoveryJsonReader object for the given dependency file paths.
98
- sig { params(dependency_file_paths: T::Array[String]).returns(NativeDiscoveryJsonReader) }
99
- def self.load_discovery_for_dependency_file_paths(dependency_file_paths)
100
- dependency_file_cache_key = cache_key_from_dependency_file_paths(dependency_file_paths)
101
- T.must(cache_dependency_file_paths_to_discovery_json_reader[dependency_file_cache_key])
102
- end
103
-
104
- # Retrieves the cached location of the discovery JSON file for the given dependency file paths.
105
- sig { params(dependency_file_paths: T::Array[String]).returns(String) }
106
- def self.get_discovery_json_path_for_dependency_file_paths(dependency_file_paths)
107
- dependency_file_cache_key = cache_key_from_dependency_file_paths(dependency_file_paths)
108
- T.must(cache_dependency_file_paths_to_discovery_json_path[dependency_file_cache_key])
109
- end
110
-
111
- sig { params(repo_contents_path: String, dependency_file: Dependabot::DependencyFile).returns(String) }
112
- def self.dependency_file_path(repo_contents_path:, dependency_file:)
113
- dep_file_path = Pathname.new(File.join(dependency_file.directory, dependency_file.name)).cleanpath.to_path
114
- dep_file_path.delete_prefix("#{repo_contents_path}/")
115
- end
116
-
117
- sig { returns(String) }
118
- def self.discovery_map_file_path
119
- File.join(discovery_directory, "discovery_map.json")
120
- end
121
-
122
- sig { params(workspace_path: String).returns(String) }
123
- def self.discovery_file_path_from_workspace_path(workspace_path)
124
- # Given an update directory (also known as a workspace path), this function returns the path where the discovery
125
- # JSON file is located. This function is called both by methods that need to write the discovery JSON file and
126
- # by methods that need to read the discovery JSON file. This function is also called by multiple processes so
127
- # we need a way to retain the data. This is accomplished by the following steps:
128
- # 1. Check a well-known file for a mapping of workspace_path => discovery file path. If found, return it.
129
- # 2. If the path is not found, generate a new path, save it to the well-known file, and return the value.
130
- discovery_map_contents = File.exist?(discovery_map_file_path) ? File.read(discovery_map_file_path) : "{}"
131
- discovery_map = T.let(JSON.parse(discovery_map_contents), T::Hash[String, String])
132
-
133
- discovery_json_path = discovery_map[workspace_path]
134
- if discovery_json_path
135
- Dependabot.logger.info("Discovery JSON path for workspace path [#{workspace_path}] found in file " \
136
- "[#{discovery_map_file_path}] at location [#{discovery_json_path}]")
137
- return discovery_json_path
138
- end
139
-
140
- # no discovery JSON path found; generate a new one, but first find a suitable location
141
- discovery_json_counter = 1
142
- new_discovery_json_path = ""
143
- loop do
144
- new_discovery_json_path = File.join(discovery_directory, "discovery.#{discovery_json_counter}.json")
145
- break unless File.exist?(new_discovery_json_path)
146
-
147
- discovery_json_counter += 1
148
- end
149
-
150
- discovery_map[workspace_path] = new_discovery_json_path
151
-
152
- File.write(discovery_map_file_path, discovery_map.to_json)
153
- Dependabot.logger.info("Discovery JSON path for workspace path [#{workspace_path}] created for file " \
154
- "[#{discovery_map_file_path}] at location [#{new_discovery_json_path}]")
155
- new_discovery_json_path
156
- end
157
-
158
- sig { params(dependency_file_paths: T::Array[String]).returns(String) }
159
- def self.cache_key_from_dependency_file_paths(dependency_file_paths)
160
- dependency_file_paths.sort.join(",")
161
- end
162
-
163
- sig { returns(String) }
164
- def self.discovery_directory
165
- t = File.join(Dir.home, ".dependabot")
166
- FileUtils.mkdir_p(t)
167
- t
168
- end
169
-
170
- sig { params(repo_contents_path: String, workspace_path: String).returns(NativeDiscoveryJsonReader) }
171
- def self.discovery_json_reader(repo_contents_path:, workspace_path:)
172
- discovery_file_path = discovery_file_path_from_workspace_path(workspace_path)
173
- discovery_json = DependencyFile.new(
174
- name: Pathname.new(discovery_file_path).cleanpath.to_path,
175
- directory: discovery_directory,
176
- type: "file",
177
- content: File.read(discovery_file_path)
178
- )
179
- NativeDiscoveryJsonReader.new(repo_contents_path: repo_contents_path, discovery_json: discovery_json)
180
- end
181
-
182
- sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
183
- attr_reader :workspace_discovery
184
-
185
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
186
- attr_reader :dependency_set
187
-
188
- sig { returns(T::Array[String]) }
189
- attr_reader :dependency_file_paths
190
-
191
- sig { params(repo_contents_path: String, discovery_json: DependencyFile).void }
192
- def initialize(repo_contents_path:, discovery_json:)
193
- @repo_contents_path = repo_contents_path
194
- @discovery_json = discovery_json
195
- @workspace_discovery = T.let(read_workspace_discovery, T.nilable(Dependabot::Nuget::NativeWorkspaceDiscovery))
196
- @dependency_set = T.let(read_dependency_set, Dependabot::FileParsers::Base::DependencySet)
197
- @dependency_file_paths = T.let(read_dependency_file_paths, T::Array[String])
198
- end
199
-
200
- private
201
-
202
- sig { returns(String) }
203
- attr_reader :repo_contents_path
204
-
205
- sig { returns(DependencyFile) }
206
- attr_reader :discovery_json
207
-
208
- sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
209
- def read_workspace_discovery
210
- return nil unless discovery_json.content
211
-
212
- parsed_json = T.let(JSON.parse(T.must(discovery_json.content)), T::Hash[String, T.untyped])
213
- NativeWorkspaceDiscovery.from_json(parsed_json)
214
- rescue JSON::ParserError
215
- raise Dependabot::DependencyFileNotParseable, discovery_json.path
216
- end
217
-
218
- sig { returns(Dependabot::FileParsers::Base::DependencySet) }
219
- def read_dependency_set
220
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
221
- return dependency_set unless workspace_discovery
222
-
223
- workspace_result = T.must(workspace_discovery)
224
- workspace_result.projects.each do |project|
225
- dependency_set += project.dependency_set
226
- end
227
- if workspace_result.dotnet_tools_json
228
- dependency_set += T.must(workspace_result.dotnet_tools_json).dependency_set
229
- end
230
- dependency_set += T.must(workspace_result.global_json).dependency_set if workspace_result.global_json
231
-
232
- dependency_set
233
- end
234
-
235
- sig { returns(T::Array[String]) }
236
- def read_dependency_file_paths
237
- dependency_file_paths = T.let([], T::Array[T.nilable(String)])
238
- dependency_file_paths << dependency_file_path_from_repo_path("global.json") if workspace_discovery&.global_json
239
- if workspace_discovery&.dotnet_tools_json
240
- dependency_file_paths << dependency_file_path_from_repo_path(".config/dotnet-tools.json")
241
- end
242
-
243
- projects = workspace_discovery&.projects || []
244
- projects.each do |project|
245
- dependency_file_paths << dependency_file_path_from_repo_path(project.file_path)
246
- dependency_file_paths += project.imported_files.map do |f|
247
- dependency_file_path_from_project_path(project.file_path, f)
248
- end
249
- dependency_file_paths += project.additional_files.map do |f|
250
- dependency_file_path_from_project_path(project.file_path, f)
251
- end
252
- end
253
-
254
- deduped_dependency_file_paths = T.let(Set.new(dependency_file_paths.compact), T::Set[String])
255
- result = deduped_dependency_file_paths.sort
256
- result
257
- end
258
-
259
- sig { params(path_parts: String).returns(T.nilable(String)) }
260
- def dependency_file_path_from_repo_path(*path_parts)
261
- path_parts = path_parts.map { |p| p.delete_prefix("/").delete_suffix("/") }
262
- normalized_repo_path = Pathname.new(path_parts.join("/")).cleanpath.to_path.delete_prefix("/")
263
- full_path = Pathname.new(File.join(repo_contents_path, normalized_repo_path)).cleanpath.to_path
264
- return unless File.exist?(full_path)
265
-
266
- normalized_repo_path = "/#{normalized_repo_path}" unless normalized_repo_path.start_with?("/")
267
- normalized_repo_path
268
- end
269
-
270
- sig { params(project_path: String, relative_file_path: String).returns(T.nilable(String)) }
271
- def dependency_file_path_from_project_path(project_path, relative_file_path)
272
- project_directory = File.dirname(project_path)
273
- dependency_file_path_from_repo_path(project_directory, relative_file_path)
274
- end
275
- end
276
- end
277
- end
@@ -1,63 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Dependabot
7
- module Nuget
8
- class NativeEvaluationDetails
9
- extend T::Sig
10
-
11
- sig { params(json: T.nilable(T::Hash[String, T.untyped])).returns(T.nilable(NativeEvaluationDetails)) }
12
- def self.from_json(json)
13
- return nil if json.nil?
14
-
15
- result_type = T.let(json.fetch("ResultType"), String)
16
- original_value = T.let(json.fetch("OriginalValue"), String)
17
- evaluated_value = T.let(json.fetch("EvaluatedValue"), String)
18
- root_property_name = T.let(json.fetch("RootPropertyName", nil), T.nilable(String))
19
- error_message = T.let(json.fetch("ErrorMessage", nil), T.nilable(String))
20
-
21
- NativeEvaluationDetails.new(result_type: result_type,
22
- original_value: original_value,
23
- evaluated_value: evaluated_value,
24
- root_property_name: root_property_name,
25
- error_message: error_message)
26
- end
27
-
28
- sig do
29
- params(result_type: String,
30
- original_value: String,
31
- evaluated_value: String,
32
- root_property_name: T.nilable(String),
33
- error_message: T.nilable(String)).void
34
- end
35
- def initialize(result_type:,
36
- original_value:,
37
- evaluated_value:,
38
- root_property_name:,
39
- error_message:)
40
- @result_type = result_type
41
- @original_value = original_value
42
- @evaluated_value = evaluated_value
43
- @root_property_name = root_property_name
44
- @error_message = error_message
45
- end
46
-
47
- sig { returns(String) }
48
- attr_reader :result_type
49
-
50
- sig { returns(String) }
51
- attr_reader :original_value
52
-
53
- sig { returns(String) }
54
- attr_reader :evaluated_value
55
-
56
- sig { returns(T.nilable(String)) }
57
- attr_reader :root_property_name
58
-
59
- sig { returns(T.nilable(String)) }
60
- attr_reader :error_message
61
- end
62
- end
63
- end
@@ -1,104 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/nuget/native_discovery/native_dependency_details"
5
- require "dependabot/nuget/native_discovery/native_property_details"
6
- require "sorbet-runtime"
7
-
8
- module Dependabot
9
- module Nuget
10
- class NativeProjectDiscovery < NativeDependencyFileDiscovery
11
- extend T::Sig
12
-
13
- # rubocop:disable Metrics/AbcSize
14
- sig do
15
- override.params(json: T.nilable(T::Hash[String, T.untyped]),
16
- directory: String).returns(T.nilable(NativeProjectDiscovery))
17
- end
18
- def self.from_json(json, directory)
19
- return nil if json.nil?
20
-
21
- file_path = File.join(directory, T.let(json.fetch("FilePath"), String))
22
- properties = T.let(json.fetch("Properties"), T::Array[T::Hash[String, T.untyped]]).map do |prop|
23
- NativePropertyDetails.from_json(prop)
24
- end
25
- target_frameworks = T.let(json.fetch("TargetFrameworks"), T::Array[String])
26
- referenced_project_paths = T.let(json.fetch("ReferencedProjectPaths"), T::Array[String])
27
- dependencies = T.let(json.fetch("Dependencies"), T::Array[T::Hash[String, T.untyped]]).filter_map do |dep|
28
- details = NativeDependencyDetails.from_json(dep)
29
- next unless details.version # can't do anything without a version
30
-
31
- version = T.must(details.version)
32
- next unless version.length.positive? # can't do anything with an empty version
33
-
34
- next if version.include? "," # can't do anything with a range
35
-
36
- next if version.include? "*" # can't do anything with a wildcard
37
-
38
- details
39
- end
40
- imported_files = T.let(json.fetch("ImportedFiles"), T::Array[String])
41
- additional_files = T.let(json.fetch("AdditionalFiles"), T::Array[String])
42
-
43
- NativeProjectDiscovery.new(file_path: file_path,
44
- properties: properties,
45
- target_frameworks: target_frameworks,
46
- referenced_project_paths: referenced_project_paths,
47
- dependencies: dependencies,
48
- imported_files: imported_files,
49
- additional_files: additional_files)
50
- end
51
- # rubocop:enable Metrics/AbcSize
52
-
53
- sig do
54
- params(file_path: String,
55
- properties: T::Array[NativePropertyDetails],
56
- target_frameworks: T::Array[String],
57
- referenced_project_paths: T::Array[String],
58
- dependencies: T::Array[NativeDependencyDetails],
59
- imported_files: T::Array[String],
60
- additional_files: T::Array[String]).void
61
- end
62
- def initialize(file_path:,
63
- properties:,
64
- target_frameworks:,
65
- referenced_project_paths:,
66
- dependencies:,
67
- imported_files:,
68
- additional_files:)
69
- super(file_path: file_path, dependencies: dependencies)
70
- @properties = properties
71
- @target_frameworks = target_frameworks
72
- @referenced_project_paths = referenced_project_paths
73
- @imported_files = imported_files
74
- @additional_files = additional_files
75
- end
76
-
77
- sig { returns(T::Array[NativePropertyDetails]) }
78
- attr_reader :properties
79
-
80
- sig { returns(T::Array[String]) }
81
- attr_reader :target_frameworks
82
-
83
- sig { returns(T::Array[String]) }
84
- attr_reader :referenced_project_paths
85
-
86
- sig { returns(T::Array[String]) }
87
- attr_reader :imported_files
88
-
89
- sig { returns(T::Array[String]) }
90
- attr_reader :additional_files
91
-
92
- sig { override.returns(Dependabot::FileParsers::Base::DependencySet) }
93
- def dependency_set
94
- if target_frameworks.empty? && file_path.end_with?("proj")
95
- Dependabot.logger.warn("Excluding project file '#{file_path}' due to unresolvable target framework")
96
- dependency_set = Dependabot::FileParsers::Base::DependencySet.new
97
- return dependency_set
98
- end
99
-
100
- super
101
- end
102
- end
103
- end
104
- end
@@ -1,43 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "sorbet-runtime"
5
-
6
- module Dependabot
7
- module Nuget
8
- class NativePropertyDetails
9
- extend T::Sig
10
-
11
- sig { params(json: T::Hash[String, T.untyped]).returns(NativePropertyDetails) }
12
- def self.from_json(json)
13
- name = T.let(json.fetch("Name"), String)
14
- value = T.let(json.fetch("Value"), String)
15
- source_file_path = T.let(json.fetch("SourceFilePath"), String)
16
-
17
- NativePropertyDetails.new(name: name,
18
- value: value,
19
- source_file_path: source_file_path)
20
- end
21
-
22
- sig do
23
- params(name: String,
24
- value: String,
25
- source_file_path: String).void
26
- end
27
- def initialize(name:, value:, source_file_path:)
28
- @name = name
29
- @value = value
30
- @source_file_path = source_file_path
31
- end
32
-
33
- sig { returns(String) }
34
- attr_reader :name
35
-
36
- sig { returns(String) }
37
- attr_reader :value
38
-
39
- sig { returns(String) }
40
- attr_reader :source_file_path
41
- end
42
- end
43
- end
@@ -1,61 +0,0 @@
1
- # typed: strong
2
- # frozen_string_literal: true
3
-
4
- require "dependabot/nuget/native_discovery/native_dependency_file_discovery"
5
- require "dependabot/nuget/native_discovery/native_project_discovery"
6
- require "dependabot/nuget/native_helpers"
7
- require "sorbet-runtime"
8
-
9
- module Dependabot
10
- module Nuget
11
- class NativeWorkspaceDiscovery
12
- extend T::Sig
13
-
14
- sig { params(json: T::Hash[String, T.untyped]).returns(NativeWorkspaceDiscovery) }
15
- def self.from_json(json)
16
- Dependabot::Nuget::NativeHelpers.ensure_no_errors(json)
17
-
18
- path = T.let(json.fetch("Path"), String)
19
- path = "/" + path unless path.start_with?("/")
20
- projects = T.let(json.fetch("Projects"), T::Array[T::Hash[String, T.untyped]]).filter_map do |project|
21
- NativeProjectDiscovery.from_json(project, path)
22
- end
23
- global_json = NativeDependencyFileDiscovery
24
- .from_json(T.let(json.fetch("GlobalJson"), T.nilable(T::Hash[String, T.untyped])), path)
25
- dotnet_tools_json = NativeDependencyFileDiscovery
26
- .from_json(T.let(json.fetch("DotNetToolsJson"),
27
- T.nilable(T::Hash[String, T.untyped])), path)
28
-
29
- NativeWorkspaceDiscovery.new(path: path,
30
- projects: projects,
31
- global_json: global_json,
32
- dotnet_tools_json: dotnet_tools_json)
33
- end
34
-
35
- sig do
36
- params(path: String,
37
- projects: T::Array[NativeProjectDiscovery],
38
- global_json: T.nilable(NativeDependencyFileDiscovery),
39
- dotnet_tools_json: T.nilable(NativeDependencyFileDiscovery)).void
40
- end
41
- def initialize(path:, projects:, global_json:, dotnet_tools_json:)
42
- @path = path
43
- @projects = projects
44
- @global_json = global_json
45
- @dotnet_tools_json = dotnet_tools_json
46
- end
47
-
48
- sig { returns(String) }
49
- attr_reader :path
50
-
51
- sig { returns(T::Array[NativeProjectDiscovery]) }
52
- attr_reader :projects
53
-
54
- sig { returns(T.nilable(NativeDependencyFileDiscovery)) }
55
- attr_reader :global_json
56
-
57
- sig { returns(T.nilable(NativeDependencyFileDiscovery)) }
58
- attr_reader :dotnet_tools_json
59
- end
60
- end
61
- end
@@ -1,105 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- #######################################################################
5
- # For more details on Dotnet version constraints, see: #
6
- # https://docs.microsoft.com/en-us/nuget/reference/package-versioning #
7
- #######################################################################
8
-
9
- require "sorbet-runtime"
10
-
11
- require "dependabot/update_checkers/base"
12
- require "dependabot/nuget/native_discovery/native_dependency_details"
13
- require "dependabot/nuget/version"
14
-
15
- module Dependabot
16
- module Nuget
17
- class NativeUpdateChecker < Dependabot::UpdateCheckers::Base
18
- class NativeRequirementsUpdater
19
- extend T::Sig
20
-
21
- sig do
22
- params(
23
- requirements: T::Array[T::Hash[Symbol, T.untyped]],
24
- dependency_details: T.nilable(Dependabot::Nuget::NativeDependencyDetails)
25
- )
26
- .void
27
- end
28
- def initialize(requirements:, dependency_details:)
29
- @requirements = requirements
30
- @dependency_details = dependency_details
31
- end
32
-
33
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
34
- def updated_requirements
35
- return requirements unless clean_version
36
-
37
- # NOTE: Order is important here. The FileUpdater needs the updated
38
- # requirement at index `i` to correspond to the previous requirement
39
- # at the same index.
40
- requirements.map do |req|
41
- next req if req.fetch(:requirement).nil?
42
- next req if req.fetch(:requirement).include?(",")
43
-
44
- new_req =
45
- if req.fetch(:requirement).include?("*")
46
- update_wildcard_requirement(req.fetch(:requirement))
47
- else
48
- # Since range requirements are excluded by the line above we can
49
- # replace anything that looks like a version with the new
50
- # version
51
- req[:requirement].sub(
52
- /#{Nuget::Version::VERSION_PATTERN}/o,
53
- clean_version.to_s
54
- )
55
- end
56
-
57
- next req if new_req == req.fetch(:requirement)
58
-
59
- new_source = req[:source]&.dup
60
- unless @dependency_details.nil?
61
- new_source = {
62
- type: "nuget_repo",
63
- source_url: @dependency_details.info_url
64
- }
65
- end
66
-
67
- req.merge({ requirement: new_req, source: new_source })
68
- end
69
- end
70
-
71
- private
72
-
73
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
74
- attr_reader :requirements
75
-
76
- sig { returns(T.class_of(Dependabot::Nuget::Version)) }
77
- def version_class
78
- Dependabot::Nuget::Version
79
- end
80
-
81
- sig { returns(T.nilable(Dependabot::Nuget::Version)) }
82
- def clean_version
83
- return unless @dependency_details&.version
84
-
85
- version_class.new(@dependency_details.version)
86
- end
87
-
88
- sig { params(req_string: String).returns(String) }
89
- def update_wildcard_requirement(req_string)
90
- return req_string if req_string == "*-*"
91
-
92
- return req_string if req_string == "*"
93
-
94
- precision = T.must(req_string.split("*").first).split(/\.|\-/).count
95
- wildcard_section = req_string.partition(/(?=[.\-]\*)/).last
96
-
97
- version_parts = T.must(clean_version).segments.first(precision)
98
- version = version_parts.join(".")
99
-
100
- version + wildcard_section
101
- end
102
- end
103
- end
104
- end
105
- end