dependabot-nuget 0.247.0 → 0.249.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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +57 -0
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +1 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +25 -5
  5. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +1 -0
  6. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +2 -0
  7. data/lib/dependabot/nuget/file_fetcher.rb +12 -8
  8. data/lib/dependabot/nuget/file_parser/dotnet_tools_json_parser.rb +1 -0
  9. data/lib/dependabot/nuget/file_parser/global_json_parser.rb +1 -0
  10. data/lib/dependabot/nuget/file_parser/packages_config_parser.rb +1 -0
  11. data/lib/dependabot/nuget/file_parser/project_file_parser.rb +1 -0
  12. data/lib/dependabot/nuget/file_parser/property_value_finder.rb +2 -0
  13. data/lib/dependabot/nuget/file_parser.rb +42 -11
  14. data/lib/dependabot/nuget/file_updater/property_value_updater.rb +1 -0
  15. data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +10 -1
  16. data/lib/dependabot/nuget/requirement.rb +17 -8
  17. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +28 -7
  18. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +70 -19
  19. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +76 -8
  20. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +25 -3
  21. data/lib/dependabot/nuget/update_checker/property_updater.rb +108 -44
  22. data/lib/dependabot/nuget/update_checker/repository_finder.rb +90 -18
  23. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +32 -9
  24. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +8 -3
  25. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +51 -13
  26. data/lib/dependabot/nuget/update_checker/version_finder.rb +167 -62
  27. data/lib/dependabot/nuget/update_checker.rb +73 -29
  28. metadata +5 -5
@@ -1,16 +1,18 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
5
+
4
6
  require "dependabot/nuget/version"
5
7
  require "dependabot/nuget/requirement"
6
8
  require "dependabot/update_checkers/base"
7
9
  require "dependabot/update_checkers/version_filters"
8
10
  require "dependabot/nuget/nuget_client"
9
- require "sorbet-runtime"
10
11
 
11
12
  module Dependabot
12
13
  module Nuget
13
14
  class UpdateChecker < Dependabot::UpdateCheckers::Base
15
+ # rubocop:disable Metrics/ClassLength
14
16
  class VersionFinder
15
17
  extend T::Sig
16
18
 
@@ -19,10 +21,24 @@ module Dependabot
19
21
 
20
22
  NUGET_RANGE_REGEX = /[\(\[].*,.*[\)\]]/
21
23
 
22
- def initialize(dependency:, dependency_files:, credentials:,
23
- ignored_versions:, raise_on_ignored: false,
24
+ sig do
25
+ params(
26
+ dependency: Dependabot::Dependency,
27
+ dependency_files: T::Array[Dependabot::DependencyFile],
28
+ credentials: T::Array[Dependabot::Credential],
29
+ ignored_versions: T::Array[String],
30
+ security_advisories: T::Array[Dependabot::SecurityAdvisory],
31
+ repo_contents_path: T.nilable(String),
32
+ raise_on_ignored: T::Boolean
33
+ ).void
34
+ end
35
+ def initialize(dependency:,
36
+ dependency_files:,
37
+ credentials:,
38
+ ignored_versions:,
24
39
  security_advisories:,
25
- repo_contents_path:)
40
+ repo_contents_path:,
41
+ raise_on_ignored: false)
26
42
  @dependency = dependency
27
43
  @dependency_files = dependency_files
28
44
  @credentials = credentials
@@ -32,53 +48,89 @@ module Dependabot
32
48
  @repo_contents_path = repo_contents_path
33
49
  end
34
50
 
51
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
35
52
  def latest_version_details
36
53
  @latest_version_details ||=
37
- begin
38
- possible_versions = versions
39
- possible_versions = filter_prereleases(possible_versions)
40
- possible_versions = filter_ignored_versions(possible_versions)
41
-
42
- find_highest_compatible_version(possible_versions)
43
- end
54
+ T.let(
55
+ begin
56
+ possible_versions = versions
57
+ possible_versions = filter_prereleases(possible_versions)
58
+ possible_versions = filter_ignored_versions(possible_versions)
59
+
60
+ find_highest_compatible_version(possible_versions)
61
+ end,
62
+ T.nilable(T::Hash[Symbol, T.untyped])
63
+ )
44
64
  end
45
65
 
66
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
46
67
  def lowest_security_fix_version_details
47
68
  @lowest_security_fix_version_details ||=
48
- begin
49
- possible_versions = versions
50
- possible_versions = filter_prereleases(possible_versions)
51
- possible_versions = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(
52
- possible_versions, security_advisories
53
- )
54
- possible_versions = filter_ignored_versions(possible_versions)
55
- possible_versions = filter_lower_versions(possible_versions)
56
-
57
- find_lowest_compatible_version(possible_versions)
58
- end
69
+ T.let(
70
+ begin
71
+ possible_versions = versions
72
+ possible_versions = filter_prereleases(possible_versions)
73
+ possible_versions = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(
74
+ possible_versions, security_advisories
75
+ )
76
+ possible_versions = filter_ignored_versions(possible_versions)
77
+ possible_versions = filter_lower_versions(possible_versions)
78
+
79
+ find_lowest_compatible_version(possible_versions)
80
+ end,
81
+ T.nilable(T::Hash[Symbol, T.untyped])
82
+ )
59
83
  end
60
84
 
85
+ sig { returns(T::Array[T::Hash[Symbol, T.nilable(T.any(Dependabot::Version, String))]]) }
61
86
  def versions
62
87
  available_v3_versions + available_v2_versions
63
88
  end
64
89
 
65
- attr_reader :dependency, :dependency_files, :credentials,
66
- :ignored_versions, :security_advisories, :repo_contents_path
90
+ sig { returns(Dependabot::Dependency) }
91
+ attr_reader :dependency
92
+
93
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
94
+ attr_reader :dependency_files
95
+
96
+ sig { returns(T::Array[Dependabot::Credential]) }
97
+ attr_reader :credentials
98
+
99
+ sig { returns(T::Array[String]) }
100
+ attr_reader :ignored_versions
101
+
102
+ sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
103
+ attr_reader :security_advisories
104
+
105
+ sig { returns(T.nilable(String)) }
106
+ attr_reader :repo_contents_path
67
107
 
68
108
  private
69
109
 
110
+ sig do
111
+ params(possible_versions: T::Array[T::Hash[Symbol, T.untyped]])
112
+ .returns(T.nilable(T::Hash[Symbol, T.untyped]))
113
+ end
70
114
  def find_highest_compatible_version(possible_versions)
71
115
  # sorted versions descending
72
116
  sorted_versions = possible_versions.sort_by { |v| v.fetch(:version) }.reverse
73
117
  find_compatible_version(sorted_versions)
74
118
  end
75
119
 
120
+ sig do
121
+ params(possible_versions: T::Array[T::Hash[Symbol, T.untyped]])
122
+ .returns(T.nilable(T::Hash[Symbol, T.untyped]))
123
+ end
76
124
  def find_lowest_compatible_version(possible_versions)
77
125
  # sorted versions ascending
78
126
  sorted_versions = possible_versions.sort_by { |v| v.fetch(:version) }
79
127
  find_compatible_version(sorted_versions)
80
128
  end
81
129
 
130
+ sig do
131
+ params(sorted_versions: T::Array[T::Hash[Symbol, T.untyped]])
132
+ .returns(T.nilable(T::Hash[Symbol, T.untyped]))
133
+ end
82
134
  def find_compatible_version(sorted_versions)
83
135
  # By checking the first version separately, we can avoid additional network requests
84
136
  first_version = sorted_versions.first
@@ -92,27 +144,37 @@ module Dependabot
92
144
  sorted_versions.find { |v| version_compatible?(v.fetch(:version)) }
93
145
  end
94
146
 
147
+ sig { params(version: T.nilable(T.any(Dependabot::Version, String))).returns(T::Boolean) }
95
148
  def version_compatible?(version)
96
149
  str_version_compatible?(version.to_s)
97
150
  end
98
151
 
152
+ sig { params(version: String).returns(T::Boolean) }
99
153
  def str_version_compatible?(version)
100
154
  compatibility_checker.compatible?(version)
101
155
  end
102
156
 
157
+ sig { returns(Dependabot::Nuget::CompatibilityChecker) }
103
158
  def compatibility_checker
104
- @compatibility_checker ||= CompatibilityChecker.new(
105
- dependency_urls: dependency_urls,
106
- dependency: dependency,
107
- tfm_finder: TfmFinder.new(
108
- dependency_files: dependency_files,
109
- credentials: credentials,
110
- repo_contents_path: repo_contents_path
159
+ @compatibility_checker ||=
160
+ T.let(
161
+ CompatibilityChecker.new(
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
+ )
169
+ ),
170
+ T.nilable(Dependabot::Nuget::CompatibilityChecker)
111
171
  )
112
- )
113
172
  end
114
173
 
115
- sig { params(possible_versions: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
174
+ sig do
175
+ params(possible_versions: T::Array[T::Hash[Symbol, T.untyped]])
176
+ .returns(T::Array[T::Hash[Symbol, T.untyped]])
177
+ end
116
178
  def filter_prereleases(possible_versions)
117
179
  filtered = possible_versions.reject do |d|
118
180
  version = d.fetch(:version)
@@ -124,7 +186,10 @@ module Dependabot
124
186
  filtered
125
187
  end
126
188
 
127
- sig { params(possible_versions: T::Array[T.untyped]).returns(T::Array[T.untyped]) }
189
+ sig do
190
+ params(possible_versions: T::Array[T::Hash[Symbol, T.untyped]])
191
+ .returns(T::Array[T::Hash[Symbol, T.untyped]])
192
+ end
128
193
  def filter_ignored_versions(possible_versions)
129
194
  filtered = possible_versions
130
195
 
@@ -147,6 +212,10 @@ module Dependabot
147
212
  filtered
148
213
  end
149
214
 
215
+ sig do
216
+ params(possible_versions: T::Array[T::Hash[Symbol, T.untyped]])
217
+ .returns(T::Array[T::Hash[Symbol, T.untyped]])
218
+ end
150
219
  def filter_lower_versions(possible_versions)
151
220
  return possible_versions unless dependency.numeric_version
152
221
 
@@ -155,12 +224,14 @@ module Dependabot
155
224
  end
156
225
  end
157
226
 
227
+ sig { params(string: String).returns(T::Array[String]) }
158
228
  def parse_requirement_string(string)
159
229
  return [string] if string.match?(NUGET_RANGE_REGEX)
160
230
 
161
231
  string.split(",").map(&:strip)
162
232
  end
163
233
 
234
+ sig { returns(T::Array[T::Hash[Symbol, T.any(Dependabot::Version, String, NilClass)]]) }
164
235
  def available_v3_versions
165
236
  v3_nuget_listings.flat_map do |listing|
166
237
  listing
@@ -181,6 +252,7 @@ module Dependabot
181
252
  end
182
253
  end
183
254
 
255
+ sig { returns(T::Array[T::Hash[Symbol, T.any(Dependabot::Version, String, NilClass)]]) }
184
256
  def available_v2_versions
185
257
  v2_nuget_listings.flat_map do |listing|
186
258
  body = listing.fetch("xml_body", [])
@@ -200,6 +272,10 @@ module Dependabot
200
272
  end
201
273
  end
202
274
 
275
+ sig do
276
+ params(entry: Nokogiri::XML::Element)
277
+ .returns(T::Hash[Symbol, T.any(Dependabot::Version, String, NilClass)])
278
+ end
203
279
  def dependency_details_from_v2_entry(entry)
204
280
  version = entry.at_xpath("./properties/Version").content.strip
205
281
  source_urls = []
@@ -221,10 +297,11 @@ module Dependabot
221
297
  end
222
298
 
223
299
  # rubocop:disable Metrics/PerceivedComplexity
300
+ sig { params(version: Dependabot::Version).returns(T::Boolean) }
224
301
  def related_to_current_pre?(version)
225
302
  current_version = dependency.numeric_version
226
303
  if current_version&.prerelease? &&
227
- current_version&.release == version.release
304
+ current_version.release == version.release
228
305
  return true
229
306
  end
230
307
 
@@ -242,36 +319,50 @@ module Dependabot
242
319
  false
243
320
  end
244
321
  end
245
-
246
322
  # rubocop:enable Metrics/PerceivedComplexity
247
323
 
324
+ sig { returns(T::Array[T::Hash[String, T.untyped]]) }
248
325
  def v3_nuget_listings
249
326
  @v3_nuget_listings ||=
250
- dependency_urls
251
- .select { |details| details.fetch(:repository_type) == "v3" }
252
- .filter_map do |url_details|
253
- versions = NugetClient.get_package_versions(dependency.name, url_details)
254
- next unless versions
255
-
256
- { "versions" => versions, "listing_details" => url_details }
257
- end
327
+ T.let(
328
+ dependency_urls
329
+ .select { |details| details.fetch(:repository_type) == "v3" }
330
+ .filter_map do |url_details|
331
+ versions = NugetClient.get_package_versions(dependency.name, url_details)
332
+ next unless versions
333
+
334
+ { "versions" => versions, "listing_details" => url_details }
335
+ end,
336
+ T.nilable(T::Array[T::Hash[String, T.untyped]])
337
+ )
258
338
  end
259
339
 
340
+ sig { returns(T::Array[T::Hash[String, T.untyped]]) }
260
341
  def v2_nuget_listings
261
342
  @v2_nuget_listings ||=
262
- dependency_urls
263
- .select { |details| details.fetch(:repository_type) == "v2" }
264
- .flat_map { |url_details| fetch_paginated_v2_nuget_listings(url_details) }
265
- .filter_map do |url_details, response|
266
- next unless response.status == 200
267
-
268
- {
269
- "xml_body" => response.body,
270
- "listing_details" => url_details
271
- }
272
- end
343
+ T.let(
344
+ dependency_urls
345
+ .select { |details| details.fetch(:repository_type) == "v2" }
346
+ .flat_map { |url_details| fetch_paginated_v2_nuget_listings(url_details) }
347
+ .filter_map do |url_details, response|
348
+ next unless response.status == 200
349
+
350
+ {
351
+ "xml_body" => response.body,
352
+ "listing_details" => url_details
353
+ }
354
+ end,
355
+ T.nilable(T::Array[T::Hash[String, T.untyped]])
356
+ )
273
357
  end
274
358
 
359
+ sig do
360
+ params(
361
+ url_details: T::Hash[Symbol, T.untyped],
362
+ results: T::Hash[T::Hash[Symbol, T.untyped], Excon::Response]
363
+ )
364
+ .returns(T::Array[T::Array[T.untyped]])
365
+ end
275
366
  def fetch_paginated_v2_nuget_listings(url_details, results = {})
276
367
  response = Dependabot::RegistryClient.get(
277
368
  url: url_details[:versions_url],
@@ -295,6 +386,7 @@ module Dependabot
295
386
  results.to_a
296
387
  end
297
388
 
389
+ sig { params(xml_body: String).returns(T.nilable(String)) }
298
390
  def fetch_v2_next_link_href(xml_body)
299
391
  doc = Nokogiri::XML(xml_body)
300
392
  doc.remove_namespaces!
@@ -307,32 +399,44 @@ module Dependabot
307
399
  nil
308
400
  end
309
401
 
402
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
310
403
  def dependency_urls
311
404
  @dependency_urls ||=
312
- RepositoryFinder.new(
313
- dependency: dependency,
314
- credentials: credentials,
315
- config_files: nuget_configs
316
- ).dependency_urls
405
+ T.let(
406
+ RepositoryFinder.new(
407
+ dependency: dependency,
408
+ credentials: credentials,
409
+ config_files: nuget_configs
410
+ ).dependency_urls,
411
+ T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
412
+ )
317
413
  end
318
414
 
415
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
319
416
  def nuget_configs
320
417
  @nuget_configs ||=
321
- dependency_files.select { |f| f.name.match?(/nuget\.config$/i) }
418
+ T.let(
419
+ dependency_files.select { |f| f.name.match?(/nuget\.config$/i) },
420
+ T.nilable(T::Array[Dependabot::DependencyFile])
421
+ )
322
422
  end
323
423
 
424
+ sig { returns(String) }
324
425
  def sanitized_name
325
426
  dependency.name.downcase
326
427
  end
327
428
 
429
+ sig { returns(T.class_of(Gem::Version)) }
328
430
  def version_class
329
431
  dependency.version_class
330
432
  end
331
433
 
434
+ sig { returns(T.class_of(Dependabot::Requirement)) }
332
435
  def requirement_class
333
436
  dependency.requirement_class
334
437
  end
335
438
 
439
+ sig { returns(T::Hash[Symbol, Integer]) }
336
440
  def excon_options
337
441
  # For large JSON files we sometimes need a little longer than for
338
442
  # other languages. For example, see:
@@ -345,6 +449,7 @@ module Dependabot
345
449
  }
346
450
  end
347
451
  end
452
+ # rubocop:enable Metrics/ClassLength
348
453
  end
349
454
  end
350
455
  end
@@ -1,47 +1,59 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "dependabot/nuget/file_parser"
5
5
  require "dependabot/update_checkers"
6
6
  require "dependabot/update_checkers/base"
7
+ require "sorbet-runtime"
7
8
 
8
9
  module Dependabot
9
10
  module Nuget
10
11
  class UpdateChecker < Dependabot::UpdateCheckers::Base
12
+ extend T::Sig
13
+
11
14
  require_relative "update_checker/version_finder"
12
15
  require_relative "update_checker/property_updater"
13
16
  require_relative "update_checker/requirements_updater"
14
17
  require_relative "update_checker/dependency_finder"
15
18
 
19
+ sig { override.returns(T.nilable(String)) }
16
20
  def latest_version
17
21
  # No need to find latest version for transitive dependencies unless they have a vulnerability.
18
22
  return dependency.version if !dependency.top_level? && !vulnerable?
19
23
 
20
24
  # if no update sources have the requisite package, then we can only assume that the current version is correct
21
- @latest_version = latest_version_details&.fetch(:version) || dependency.version
25
+ @latest_version = T.let(
26
+ latest_version_details&.fetch(:version)&.to_s || dependency.version,
27
+ T.nilable(String)
28
+ )
22
29
  end
23
30
 
31
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
24
32
  def latest_resolvable_version
25
33
  # We always want a full unlock since any package update could update peer dependencies as well.
26
34
  # To force a full unlock instead of an own unlock, we return nil.
27
35
  nil
28
36
  end
29
37
 
38
+ sig { override.returns(Dependabot::Nuget::Version) }
30
39
  def lowest_security_fix_version
31
40
  lowest_security_fix_version_details&.fetch(:version)
32
41
  end
33
42
 
43
+ sig { override.returns(T.nilable(Dependabot::Version)) }
34
44
  def lowest_resolvable_security_fix_version
35
45
  return nil if version_comes_from_multi_dependency_property?
36
46
 
37
47
  lowest_security_fix_version
38
48
  end
39
49
 
50
+ sig { override.returns(NilClass) }
40
51
  def latest_resolvable_version_with_no_unlock
41
52
  # Irrelevant, since Nuget has a single dependency file
42
53
  nil
43
54
  end
44
55
 
56
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
45
57
  def updated_requirements
46
58
  RequirementsUpdater.new(
47
59
  requirements: dependency.requirements,
@@ -50,6 +62,7 @@ module Dependabot
50
62
  ).updated_requirements
51
63
  end
52
64
 
65
+ sig { returns(T::Boolean) }
53
66
  def up_to_date?
54
67
  # No need to update transitive dependencies unless they have a vulnerability.
55
68
  return true if !dependency.top_level? && !vulnerable?
@@ -62,6 +75,7 @@ module Dependabot
62
75
  super
63
76
  end
64
77
 
78
+ sig { returns(T::Boolean) }
65
79
  def requirements_unlocked_or_can_be?
66
80
  # If any requirements have an uninterpolated property in them then
67
81
  # that property couldn't be found, and the requirement therefore
@@ -73,6 +87,7 @@ module Dependabot
73
87
 
74
88
  private
75
89
 
90
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
76
91
  def preferred_resolvable_version_details
77
92
  # If this dependency is vulnerable, prefer trying to update to the
78
93
  # lowest_resolvable_security_fix_version. Otherwise update all the way
@@ -82,6 +97,7 @@ module Dependabot
82
97
  latest_version_details
83
98
  end
84
99
 
100
+ sig { override.returns(T::Boolean) }
85
101
  def latest_version_resolvable_with_full_unlock?
86
102
  # We always want a full unlock since any package update could update peer dependencies as well.
87
103
  return true unless version_comes_from_multi_dependency_property?
@@ -89,6 +105,7 @@ module Dependabot
89
105
  property_updater.update_possible?
90
106
  end
91
107
 
108
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
92
109
  def updated_dependencies_after_full_unlock
93
110
  return property_updater.updated_dependencies if version_comes_from_multi_dependency_property?
94
111
 
@@ -96,7 +113,7 @@ module Dependabot
96
113
 
97
114
  updated_dependency = Dependency.new(
98
115
  name: dependency.name,
99
- version: latest_version&.to_s,
116
+ version: latest_version,
100
117
  requirements: updated_requirements,
101
118
  previous_version: dependency.version,
102
119
  previous_requirements: dependency.requirements,
@@ -112,47 +129,66 @@ module Dependabot
112
129
  updated_dependencies
113
130
  end
114
131
 
132
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
115
133
  def preferred_version_details
116
134
  return lowest_security_fix_version_details if vulnerable?
117
135
 
118
136
  latest_version_details
119
137
  end
120
138
 
139
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
121
140
  def latest_version_details
122
- @latest_version_details ||= version_finder.latest_version_details
141
+ @latest_version_details ||=
142
+ T.let(
143
+ version_finder.latest_version_details,
144
+ T.nilable(T::Hash[Symbol, T.untyped])
145
+ )
123
146
  end
124
147
 
148
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
125
149
  def lowest_security_fix_version_details
126
150
  @lowest_security_fix_version_details ||=
127
- version_finder.lowest_security_fix_version_details
151
+ T.let(
152
+ version_finder.lowest_security_fix_version_details,
153
+ T.nilable(T::Hash[Symbol, T.untyped])
154
+ )
128
155
  end
129
156
 
157
+ sig { returns(Dependabot::Nuget::UpdateChecker::VersionFinder) }
130
158
  def version_finder
131
159
  @version_finder ||=
132
- VersionFinder.new(
133
- dependency: dependency,
134
- dependency_files: dependency_files,
135
- credentials: credentials,
136
- ignored_versions: ignored_versions,
137
- raise_on_ignored: @raise_on_ignored,
138
- security_advisories: security_advisories,
139
- repo_contents_path: @repo_contents_path
160
+ T.let(
161
+ VersionFinder.new(
162
+ dependency: dependency,
163
+ dependency_files: dependency_files,
164
+ credentials: credentials,
165
+ ignored_versions: ignored_versions,
166
+ raise_on_ignored: @raise_on_ignored,
167
+ security_advisories: security_advisories,
168
+ repo_contents_path: @repo_contents_path
169
+ ),
170
+ T.nilable(Dependabot::Nuget::UpdateChecker::VersionFinder)
140
171
  )
141
172
  end
142
173
 
174
+ sig { returns(Dependabot::Nuget::UpdateChecker::PropertyUpdater) }
143
175
  def property_updater
144
176
  @property_updater ||=
145
- PropertyUpdater.new(
146
- dependency: dependency,
147
- dependency_files: dependency_files,
148
- target_version_details: latest_version_details,
149
- credentials: credentials,
150
- ignored_versions: ignored_versions,
151
- raise_on_ignored: @raise_on_ignored,
152
- repo_contents_path: @repo_contents_path
177
+ T.let(
178
+ PropertyUpdater.new(
179
+ dependency: dependency,
180
+ dependency_files: dependency_files,
181
+ target_version_details: latest_version_details,
182
+ credentials: credentials,
183
+ ignored_versions: ignored_versions,
184
+ raise_on_ignored: @raise_on_ignored,
185
+ repo_contents_path: @repo_contents_path
186
+ ),
187
+ T.nilable(Dependabot::Nuget::UpdateChecker::PropertyUpdater)
153
188
  )
154
189
  end
155
190
 
191
+ sig { returns(T::Boolean) }
156
192
  def version_comes_from_multi_dependency_property?
157
193
  declarations_using_a_property.any? do |requirement|
158
194
  property_name = requirement.fetch(:metadata).fetch(:property_name)
@@ -167,20 +203,28 @@ module Dependabot
167
203
  end
168
204
  end
169
205
 
206
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
170
207
  def declarations_using_a_property
171
208
  @declarations_using_a_property ||=
172
- dependency.requirements
173
- .select { |req| req.dig(:metadata, :property_name) }
209
+ T.let(
210
+ dependency.requirements
211
+ .select { |req| req.dig(:metadata, :property_name) },
212
+ T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
213
+ )
174
214
  end
175
215
 
216
+ sig { returns(T::Array[Dependabot::Dependency]) }
176
217
  def all_property_based_dependencies
177
218
  @all_property_based_dependencies ||=
178
- Nuget::FileParser.new(
179
- dependency_files: dependency_files,
180
- source: nil
181
- ).parse.select do |dep|
182
- dep.requirements.any? { |req| req.dig(:metadata, :property_name) }
183
- end
219
+ T.let(
220
+ Nuget::FileParser.new(
221
+ dependency_files: dependency_files,
222
+ source: nil
223
+ ).parse.select do |dep|
224
+ dep.requirements.any? { |req| req.dig(:metadata, :property_name) }
225
+ end,
226
+ T.nilable(T::Array[Dependabot::Dependency])
227
+ )
184
228
  end
185
229
  end
186
230
  end
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.247.0
4
+ version: 0.249.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-03-14 00:00:00.000000000 Z
11
+ date: 2024-03-28 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.247.0
19
+ version: 0.249.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.247.0
26
+ version: 0.249.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubyzip
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -385,7 +385,7 @@ licenses:
385
385
  - Nonstandard
386
386
  metadata:
387
387
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
388
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.247.0
388
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.249.0
389
389
  post_install_message:
390
390
  rdoc_options: []
391
391
  require_paths: