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.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +57 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +25 -5
- data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +1 -0
- data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +2 -0
- data/lib/dependabot/nuget/file_fetcher.rb +12 -8
- data/lib/dependabot/nuget/file_parser/dotnet_tools_json_parser.rb +1 -0
- data/lib/dependabot/nuget/file_parser/global_json_parser.rb +1 -0
- data/lib/dependabot/nuget/file_parser/packages_config_parser.rb +1 -0
- data/lib/dependabot/nuget/file_parser/project_file_parser.rb +1 -0
- data/lib/dependabot/nuget/file_parser/property_value_finder.rb +2 -0
- data/lib/dependabot/nuget/file_parser.rb +42 -11
- data/lib/dependabot/nuget/file_updater/property_value_updater.rb +1 -0
- data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +10 -1
- data/lib/dependabot/nuget/requirement.rb +17 -8
- data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +28 -7
- data/lib/dependabot/nuget/update_checker/dependency_finder.rb +70 -19
- data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +76 -8
- data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +25 -3
- data/lib/dependabot/nuget/update_checker/property_updater.rb +108 -44
- data/lib/dependabot/nuget/update_checker/repository_finder.rb +90 -18
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +32 -9
- data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +8 -3
- data/lib/dependabot/nuget/update_checker/tfm_finder.rb +51 -13
- data/lib/dependabot/nuget/update_checker/version_finder.rb +167 -62
- data/lib/dependabot/nuget/update_checker.rb +73 -29
- metadata +5 -5
@@ -1,8 +1,10 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
5
5
|
require "nokogiri"
|
6
|
+
require "sorbet-runtime"
|
7
|
+
|
6
8
|
require "dependabot/errors"
|
7
9
|
require "dependabot/update_checkers/base"
|
8
10
|
require "dependabot/registry_client"
|
@@ -12,23 +14,34 @@ require "dependabot/nuget/http_response_helpers"
|
|
12
14
|
module Dependabot
|
13
15
|
module Nuget
|
14
16
|
class RepositoryFinder
|
17
|
+
extend T::Sig
|
18
|
+
|
15
19
|
DEFAULT_REPOSITORY_URL = "https://api.nuget.org/v3/index.json"
|
16
20
|
DEFAULT_REPOSITORY_API_KEY = "nuget.org"
|
17
21
|
|
22
|
+
sig do
|
23
|
+
params(
|
24
|
+
dependency: Dependabot::Dependency,
|
25
|
+
credentials: T::Array[Dependabot::Credential],
|
26
|
+
config_files: T::Array[Dependabot::DependencyFile]
|
27
|
+
).void
|
28
|
+
end
|
18
29
|
def initialize(dependency:, credentials:, config_files: [])
|
19
30
|
@dependency = dependency
|
20
31
|
@credentials = credentials
|
21
32
|
@config_files = config_files
|
22
33
|
end
|
23
34
|
|
35
|
+
sig { returns(T::Array[T::Hash[Symbol, String]]) }
|
24
36
|
def dependency_urls
|
25
37
|
find_dependency_urls
|
26
38
|
end
|
27
39
|
|
40
|
+
sig { returns(T::Array[T::Hash[Symbol, String]]) }
|
28
41
|
def known_repositories
|
29
42
|
return @known_repositories if @known_repositories
|
30
43
|
|
31
|
-
@known_repositories
|
44
|
+
@known_repositories ||= T.let([], T.nilable(T::Array[T::Hash[Symbol, String]]))
|
32
45
|
@known_repositories += credential_repositories
|
33
46
|
@known_repositories += config_file_repositories
|
34
47
|
|
@@ -40,6 +53,7 @@ module Dependabot
|
|
40
53
|
@known_repositories.uniq
|
41
54
|
end
|
42
55
|
|
56
|
+
sig { params(dependency_name: String).returns(T::Hash[Symbol, T.untyped]) }
|
43
57
|
def self.get_default_repository_details(dependency_name)
|
44
58
|
{
|
45
59
|
base_url: "https://api.nuget.org/v3-flatcontainer/",
|
@@ -56,21 +70,33 @@ module Dependabot
|
|
56
70
|
|
57
71
|
private
|
58
72
|
|
59
|
-
|
73
|
+
sig { returns(Dependabot::Dependency) }
|
74
|
+
attr_reader :dependency
|
75
|
+
|
76
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
77
|
+
attr_reader :credentials
|
78
|
+
|
79
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
80
|
+
attr_reader :config_files
|
60
81
|
|
82
|
+
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
61
83
|
def find_dependency_urls
|
62
84
|
@find_dependency_urls ||=
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
85
|
+
T.let(
|
86
|
+
known_repositories.flat_map do |details|
|
87
|
+
if details.fetch(:url) == DEFAULT_REPOSITORY_URL
|
88
|
+
# Save a request for the default URL, since we already know how
|
89
|
+
# it addresses packages
|
90
|
+
next default_repository_details
|
91
|
+
end
|
69
92
|
|
70
|
-
|
71
|
-
|
93
|
+
build_url_for_details(details)
|
94
|
+
end.compact.uniq,
|
95
|
+
T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
|
96
|
+
)
|
72
97
|
end
|
73
98
|
|
99
|
+
sig { params(repo_details: T::Hash[Symbol, T.untyped]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
74
100
|
def build_url_for_details(repo_details)
|
75
101
|
url = repo_details.fetch(:url)
|
76
102
|
url_obj = URI.parse(url)
|
@@ -86,6 +112,7 @@ module Dependabot
|
|
86
112
|
details
|
87
113
|
end
|
88
114
|
|
115
|
+
sig { params(repo_details: T::Hash[Symbol, T.untyped]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
89
116
|
def build_url_for_details_remote(repo_details)
|
90
117
|
response = get_repo_metadata(repo_details)
|
91
118
|
check_repo_response(response, repo_details)
|
@@ -118,11 +145,12 @@ module Dependabot
|
|
118
145
|
|
119
146
|
details
|
120
147
|
rescue JSON::ParserError
|
121
|
-
build_v2_url(response, repo_details)
|
148
|
+
build_v2_url(T.must(response), repo_details)
|
122
149
|
rescue Excon::Error::Timeout, Excon::Error::Socket
|
123
150
|
handle_timeout(repo_metadata_url: repo_details.fetch(:url))
|
124
151
|
end
|
125
152
|
|
153
|
+
sig { params(repo_details: T::Hash[Symbol, T.untyped]).returns(Excon::Response) }
|
126
154
|
def get_repo_metadata(repo_details)
|
127
155
|
url = repo_details.fetch(:url)
|
128
156
|
cache = CacheManager.cache("repo_finder_metadatacache")
|
@@ -138,6 +166,7 @@ module Dependabot
|
|
138
166
|
end
|
139
167
|
end
|
140
168
|
|
169
|
+
sig { params(metadata: T::Hash[String, T::Array[T::Hash[String, T.untyped]]]).returns(T.nilable(String)) }
|
141
170
|
def base_url_from_v3_metadata(metadata)
|
142
171
|
metadata
|
143
172
|
.fetch("resources", [])
|
@@ -145,6 +174,7 @@ module Dependabot
|
|
145
174
|
&.fetch("@id")
|
146
175
|
end
|
147
176
|
|
177
|
+
sig { params(metadata: T::Hash[String, T::Array[T::Hash[String, T.untyped]]]).returns(T.nilable(String)) }
|
148
178
|
def registration_url_from_v3_metadata(metadata)
|
149
179
|
allowed_registration_types = %w(
|
150
180
|
RegistrationsBaseUrl
|
@@ -159,6 +189,7 @@ module Dependabot
|
|
159
189
|
&.fetch("@id")
|
160
190
|
end
|
161
191
|
|
192
|
+
sig { params(metadata: T::Hash[String, T::Array[T::Hash[String, T.untyped]]]).returns(T.nilable(String)) }
|
162
193
|
def search_url_from_v3_metadata(metadata)
|
163
194
|
# allowable values from here: https://learn.microsoft.com/en-us/nuget/api/search-query-service-resource#versioning
|
164
195
|
allowed_search_types = %w(
|
@@ -173,6 +204,13 @@ module Dependabot
|
|
173
204
|
&.fetch("@id")
|
174
205
|
end
|
175
206
|
|
207
|
+
sig do
|
208
|
+
params(
|
209
|
+
response: Excon::Response,
|
210
|
+
repo_details: T::Hash[Symbol, T.untyped]
|
211
|
+
)
|
212
|
+
.returns(T::Hash[Symbol, T.untyped])
|
213
|
+
end
|
176
214
|
def build_v2_url(response, repo_details)
|
177
215
|
doc = Nokogiri::XML(response.body)
|
178
216
|
|
@@ -194,6 +232,7 @@ module Dependabot
|
|
194
232
|
}
|
195
233
|
end
|
196
234
|
|
235
|
+
sig { params(response: Excon::Response, details: T::Hash[Symbol, T.untyped]).void }
|
197
236
|
def check_repo_response(response, details)
|
198
237
|
return unless [401, 402, 403].include?(response.status)
|
199
238
|
raise if details.fetch(:url) == DEFAULT_REPOSITORY_URL
|
@@ -201,19 +240,25 @@ module Dependabot
|
|
201
240
|
raise PrivateSourceAuthenticationFailure, details.fetch(:url)
|
202
241
|
end
|
203
242
|
|
243
|
+
sig { params(repo_metadata_url: String).returns(T.noreturn) }
|
204
244
|
def handle_timeout(repo_metadata_url:)
|
205
245
|
raise if repo_metadata_url == DEFAULT_REPOSITORY_URL
|
206
246
|
|
207
247
|
raise PrivateSourceTimedOut, repo_metadata_url
|
208
248
|
end
|
209
249
|
|
250
|
+
sig { returns(T::Array[T::Hash[Symbol, String]]) }
|
210
251
|
def credential_repositories
|
211
252
|
@credential_repositories ||=
|
212
|
-
|
213
|
-
|
214
|
-
|
253
|
+
T.let(
|
254
|
+
credentials
|
255
|
+
.select { |cred| cred["type"] == "nuget_feed" && cred["url"] }
|
256
|
+
.map { |c| { url: c.fetch("url"), token: c["token"] } },
|
257
|
+
T.nilable(T::Array[T::Hash[Symbol, String]])
|
258
|
+
)
|
215
259
|
end
|
216
260
|
|
261
|
+
sig { returns(T::Array[T::Hash[Symbol, String]]) }
|
217
262
|
def config_file_repositories
|
218
263
|
config_files.flat_map { |file| repos_from_config_file(file) }
|
219
264
|
end
|
@@ -222,13 +267,14 @@ module Dependabot
|
|
222
267
|
# rubocop:disable Metrics/PerceivedComplexity
|
223
268
|
# rubocop:disable Metrics/MethodLength
|
224
269
|
# rubocop:disable Metrics/AbcSize
|
270
|
+
sig { params(config_file: Dependabot::DependencyFile).returns(T::Array[T::Hash[Symbol, String]]) }
|
225
271
|
def repos_from_config_file(config_file)
|
226
272
|
doc = Nokogiri::XML(config_file.content)
|
227
273
|
doc.remove_namespaces!
|
228
274
|
# analogous to having a root config with the default repository
|
229
275
|
base_sources = [{ url: DEFAULT_REPOSITORY_URL, key: "nuget.org" }]
|
230
276
|
|
231
|
-
sources = []
|
277
|
+
sources = T.let([], T::Array[T::Hash[Symbol, String]])
|
232
278
|
|
233
279
|
# regular package sources
|
234
280
|
doc.css("configuration > packageSources").children.each do |node|
|
@@ -269,6 +315,23 @@ module Dependabot
|
|
269
315
|
known_urls.include?(s.fetch(:url))
|
270
316
|
end
|
271
317
|
|
318
|
+
# filter out based on packageSourceMapping
|
319
|
+
package_mapping_elements = doc.xpath("/configuration/packageSourceMapping/packageSource/package[@pattern]")
|
320
|
+
matching_package_elements = package_mapping_elements.select do |package_element|
|
321
|
+
pattern = package_element.attribute("pattern").value
|
322
|
+
|
323
|
+
# reusing this function for a case insensitive GLOB pattern patch (e.g., "Microsoft.Azure.*")
|
324
|
+
File.fnmatch(pattern, @dependency.name, File::FNM_CASEFOLD)
|
325
|
+
end
|
326
|
+
longest_matching_package_element = matching_package_elements.max_by do |package_element|
|
327
|
+
package_element.attribute("pattern").value.length
|
328
|
+
end
|
329
|
+
matching_key = longest_matching_package_element&.parent&.attribute("key")&.value
|
330
|
+
if matching_key
|
331
|
+
# found a matching source, only keep that one
|
332
|
+
sources.select! { |s| s.fetch(:key) == matching_key }
|
333
|
+
end
|
334
|
+
|
272
335
|
add_config_file_credentials(sources: sources, doc: doc)
|
273
336
|
sources.each { |details| details.delete(:key) }
|
274
337
|
|
@@ -279,11 +342,13 @@ module Dependabot
|
|
279
342
|
# rubocop:enable Metrics/PerceivedComplexity
|
280
343
|
# rubocop:enable Metrics/CyclomaticComplexity
|
281
344
|
|
345
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
282
346
|
def default_repository_details
|
283
347
|
RepositoryFinder.get_default_repository_details(dependency.name)
|
284
348
|
end
|
285
349
|
|
286
350
|
# rubocop:disable Metrics/PerceivedComplexity
|
351
|
+
sig { params(doc: Nokogiri::XML::Document).returns(T::Array[String]) }
|
287
352
|
def disabled_sources(doc)
|
288
353
|
doc.css("configuration > disabledPackageSources > add").filter_map do |node|
|
289
354
|
value = node.attribute("value")&.value ||
|
@@ -298,6 +363,13 @@ module Dependabot
|
|
298
363
|
# rubocop:enable Metrics/PerceivedComplexity
|
299
364
|
|
300
365
|
# rubocop:disable Metrics/PerceivedComplexity
|
366
|
+
sig do
|
367
|
+
params(
|
368
|
+
sources: T::Array[T::Hash[Symbol, T.nilable(String)]],
|
369
|
+
doc: Nokogiri::XML::Document
|
370
|
+
)
|
371
|
+
.void
|
372
|
+
end
|
301
373
|
def add_config_file_credentials(sources:, doc:)
|
302
374
|
sources.each do |source_details|
|
303
375
|
key = source_details.fetch(:key)
|
@@ -329,11 +401,10 @@ module Dependabot
|
|
329
401
|
# Any non-ascii characters in the tag with cause a syntax error
|
330
402
|
next source_details[:token] = nil
|
331
403
|
end
|
332
|
-
|
333
|
-
sources
|
334
404
|
end
|
335
405
|
# rubocop:enable Metrics/PerceivedComplexity
|
336
406
|
|
407
|
+
sig { params(string: String).returns(String) }
|
337
408
|
def expand_windows_style_environment_variables(string)
|
338
409
|
# NuGet.Config files can have Windows-style environment variables that need to be replaced
|
339
410
|
# https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file#using-environment-variables
|
@@ -352,6 +423,7 @@ module Dependabot
|
|
352
423
|
end
|
353
424
|
end
|
354
425
|
|
426
|
+
sig { params(token: T.nilable(String)).returns(T::Hash[String, String]) }
|
355
427
|
def auth_header_for_token(token)
|
356
428
|
return {} unless token
|
357
429
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
#######################################################################
|
@@ -6,6 +6,8 @@
|
|
6
6
|
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning #
|
7
7
|
#######################################################################
|
8
8
|
|
9
|
+
require "sorbet-runtime"
|
10
|
+
|
9
11
|
require "dependabot/update_checkers/base"
|
10
12
|
require "dependabot/nuget/version"
|
11
13
|
|
@@ -13,14 +15,25 @@ module Dependabot
|
|
13
15
|
module Nuget
|
14
16
|
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
15
17
|
class RequirementsUpdater
|
18
|
+
extend T::Sig
|
19
|
+
|
20
|
+
sig do
|
21
|
+
params(
|
22
|
+
requirements: T::Array[T::Hash[Symbol, T.untyped]],
|
23
|
+
latest_version: T.nilable(T.any(String, Dependabot::Nuget::Version)),
|
24
|
+
source_details: T.nilable(T::Hash[Symbol, T.untyped])
|
25
|
+
)
|
26
|
+
.void
|
27
|
+
end
|
16
28
|
def initialize(requirements:, latest_version:, source_details:)
|
17
29
|
@requirements = requirements
|
18
30
|
@source_details = source_details
|
19
31
|
return unless latest_version
|
20
32
|
|
21
|
-
@latest_version = version_class.new(latest_version)
|
33
|
+
@latest_version = T.let(version_class.new(latest_version), Dependabot::Nuget::Version)
|
22
34
|
end
|
23
35
|
|
36
|
+
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
24
37
|
def updated_requirements
|
25
38
|
return requirements unless latest_version
|
26
39
|
|
@@ -52,32 +65,42 @@ module Dependabot
|
|
52
65
|
|
53
66
|
private
|
54
67
|
|
55
|
-
|
68
|
+
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
69
|
+
attr_reader :requirements
|
70
|
+
|
71
|
+
sig { returns(T.nilable(Dependabot::Nuget::Version)) }
|
72
|
+
attr_reader :latest_version
|
73
|
+
|
74
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
75
|
+
attr_reader :source_details
|
56
76
|
|
77
|
+
sig { returns(T.class_of(Dependabot::Nuget::Version)) }
|
57
78
|
def version_class
|
58
|
-
Nuget::Version
|
79
|
+
Dependabot::Nuget::Version
|
59
80
|
end
|
60
81
|
|
82
|
+
sig { params(req_string: String).returns(String) }
|
61
83
|
def update_wildcard_requirement(req_string)
|
62
84
|
return req_string if req_string == "*-*"
|
63
85
|
|
64
86
|
return req_string if req_string == "*"
|
65
87
|
|
66
|
-
precision = req_string.split("*").first.split(/\.|\-/).count
|
88
|
+
precision = T.must(req_string.split("*").first).split(/\.|\-/).count
|
67
89
|
wildcard_section = req_string.partition(/(?=[.\-]\*)/).last
|
68
90
|
|
69
|
-
version_parts = latest_version.segments.first(precision)
|
91
|
+
version_parts = T.must(latest_version).segments.first(precision)
|
70
92
|
version = version_parts.join(".")
|
71
93
|
|
72
94
|
version + wildcard_section
|
73
95
|
end
|
74
96
|
|
97
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
75
98
|
def updated_source
|
76
99
|
{
|
77
100
|
type: "nuget_repo",
|
78
|
-
url: source_details
|
79
|
-
nuspec_url: source_details
|
80
|
-
source_url: source_details
|
101
|
+
url: source_details&.fetch(:repo_url),
|
102
|
+
nuspec_url: source_details&.fetch(:nuspec_url),
|
103
|
+
source_url: source_details&.fetch(:source_url)
|
81
104
|
}
|
82
105
|
end
|
83
106
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/update_checkers/base"
|
5
7
|
require "dependabot/nuget/version"
|
6
8
|
require "dependabot/nuget/requirement"
|
@@ -10,19 +12,22 @@ require "dependabot/shared_helpers"
|
|
10
12
|
module Dependabot
|
11
13
|
module Nuget
|
12
14
|
class TfmComparer
|
15
|
+
extend T::Sig
|
16
|
+
|
17
|
+
sig { params(project_tfms: T::Array[String], package_tfms: T::Array[String]).returns(T::Boolean) }
|
13
18
|
def self.are_frameworks_compatible?(project_tfms, package_tfms)
|
14
19
|
return false if package_tfms.empty?
|
15
20
|
return false if project_tfms.empty?
|
16
21
|
|
17
22
|
key = "project_ftms:#{project_tfms.sort.join(',')}:package_tfms:#{package_tfms.sort.join(',')}".downcase
|
18
23
|
|
19
|
-
@cached_framework_check ||= {}
|
24
|
+
@cached_framework_check ||= T.let({}, T.nilable(T::Hash[String, T::Boolean]))
|
20
25
|
unless @cached_framework_check.key?(key)
|
21
26
|
@cached_framework_check[key] =
|
22
27
|
NativeHelpers.run_nuget_framework_check(project_tfms,
|
23
28
|
package_tfms)
|
24
29
|
end
|
25
|
-
@cached_framework_check[key]
|
30
|
+
T.must(@cached_framework_check[key])
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "excon"
|
5
5
|
require "nokogiri"
|
6
|
+
require "sorbet-runtime"
|
6
7
|
|
7
8
|
require "dependabot/update_checkers/base"
|
8
9
|
require "dependabot/nuget/version"
|
@@ -13,15 +14,25 @@ require "dependabot/shared_helpers"
|
|
13
14
|
module Dependabot
|
14
15
|
module Nuget
|
15
16
|
class TfmFinder
|
17
|
+
extend T::Sig
|
18
|
+
|
16
19
|
require "dependabot/nuget/file_parser/packages_config_parser"
|
17
20
|
require "dependabot/nuget/file_parser/project_file_parser"
|
18
21
|
|
22
|
+
sig do
|
23
|
+
params(
|
24
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
25
|
+
credentials: T::Array[Dependabot::Credential],
|
26
|
+
repo_contents_path: T.nilable(String)
|
27
|
+
).void
|
28
|
+
end
|
19
29
|
def initialize(dependency_files:, credentials:, repo_contents_path:)
|
20
30
|
@dependency_files = dependency_files
|
21
31
|
@credentials = credentials
|
22
32
|
@repo_contents_path = repo_contents_path
|
23
33
|
end
|
24
34
|
|
35
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Array[String]) }
|
25
36
|
def frameworks(dependency)
|
26
37
|
tfms = Set.new
|
27
38
|
tfms += project_file_tfms(dependency)
|
@@ -31,14 +42,23 @@ module Dependabot
|
|
31
42
|
|
32
43
|
private
|
33
44
|
|
34
|
-
|
45
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
46
|
+
attr_reader :dependency_files
|
47
|
+
|
48
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
49
|
+
attr_reader :credentials
|
50
|
+
|
51
|
+
sig { returns(T.nilable(String)) }
|
52
|
+
attr_reader :repo_contents_path
|
35
53
|
|
54
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Array[String]) }
|
36
55
|
def project_file_tfms(dependency)
|
37
56
|
project_files_with_dependency(dependency).flat_map do |file|
|
38
57
|
project_file_parser.target_frameworks(project_file: file)
|
39
58
|
end
|
40
59
|
end
|
41
60
|
|
61
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Array[Dependabot::DependencyFile]) }
|
42
62
|
def project_files_with_dependency(dependency)
|
43
63
|
project_files.select do |file|
|
44
64
|
packages_config_contains_dependency?(file, dependency) ||
|
@@ -46,6 +66,7 @@ module Dependabot
|
|
46
66
|
end
|
47
67
|
end
|
48
68
|
|
69
|
+
sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
49
70
|
def packages_config_contains_dependency?(file, dependency)
|
50
71
|
config_file = find_packages_config_file(file)
|
51
72
|
return false unless config_file
|
@@ -56,36 +77,48 @@ module Dependabot
|
|
56
77
|
end
|
57
78
|
end
|
58
79
|
|
80
|
+
sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
59
81
|
def project_file_contains_dependency?(file, dependency)
|
60
82
|
project_file_parser.dependency_set(project_file: file).dependencies.any? do |d|
|
61
83
|
d.name.casecmp(dependency.name)&.zero?
|
62
84
|
end
|
63
85
|
end
|
64
86
|
|
87
|
+
sig { params(file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::DependencyFile)) }
|
65
88
|
def find_packages_config_file(file)
|
66
89
|
return file if file.name.end_with?("packages.config")
|
67
90
|
|
68
91
|
filename = File.basename(file.name)
|
69
92
|
search_path = file.name.sub(filename, "packages.config")
|
70
93
|
|
71
|
-
dependency_files.find { |f| f.name.casecmp(search_path)
|
94
|
+
dependency_files.find { |f| f.name.casecmp(search_path)&.zero? }
|
72
95
|
end
|
73
96
|
|
97
|
+
sig { returns(T::Array[String]) }
|
74
98
|
def project_import_file_tfms
|
75
|
-
@project_import_file_tfms ||=
|
76
|
-
|
77
|
-
|
99
|
+
@project_import_file_tfms ||=
|
100
|
+
T.let(
|
101
|
+
project_import_files.flat_map do |file|
|
102
|
+
project_file_parser.target_frameworks(project_file: file)
|
103
|
+
end,
|
104
|
+
T.nilable(T::Array[String])
|
105
|
+
)
|
78
106
|
end
|
79
107
|
|
108
|
+
sig { returns(FileParser::ProjectFileParser) }
|
80
109
|
def project_file_parser
|
81
110
|
@project_file_parser ||=
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
111
|
+
T.let(
|
112
|
+
FileParser::ProjectFileParser.new(
|
113
|
+
dependency_files: dependency_files,
|
114
|
+
credentials: credentials,
|
115
|
+
repo_contents_path: repo_contents_path
|
116
|
+
),
|
117
|
+
T.nilable(FileParser::ProjectFileParser)
|
86
118
|
)
|
87
119
|
end
|
88
120
|
|
121
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
89
122
|
def project_files
|
90
123
|
projfile = /\.[a-z]{2}proj$/
|
91
124
|
packageprops = /[Dd]irectory.[Pp]ackages.props/
|
@@ -96,12 +129,14 @@ module Dependabot
|
|
96
129
|
end
|
97
130
|
end
|
98
131
|
|
132
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
99
133
|
def packages_config_files
|
100
134
|
dependency_files.select do |f|
|
101
|
-
f.name.split("/").last
|
135
|
+
f.name.split("/").last&.casecmp("packages.config")&.zero?
|
102
136
|
end
|
103
137
|
end
|
104
138
|
|
139
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
105
140
|
def project_import_files
|
106
141
|
dependency_files -
|
107
142
|
project_files -
|
@@ -111,16 +146,19 @@ module Dependabot
|
|
111
146
|
[dotnet_tools_json]
|
112
147
|
end
|
113
148
|
|
149
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
114
150
|
def nuget_configs
|
115
151
|
dependency_files.select { |f| f.name.match?(/nuget\.config$/i) }
|
116
152
|
end
|
117
153
|
|
154
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
118
155
|
def global_json
|
119
|
-
dependency_files.find { |f| f.name.casecmp("global.json")
|
156
|
+
dependency_files.find { |f| f.name.casecmp("global.json")&.zero? }
|
120
157
|
end
|
121
158
|
|
159
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
122
160
|
def dotnet_tools_json
|
123
|
-
dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json")
|
161
|
+
dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json")&.zero? }
|
124
162
|
end
|
125
163
|
end
|
126
164
|
end
|