dependabot-nuget 0.247.0 → 0.249.0

Sign up to get free protection for your applications and to get access to all the features.
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: