dependabot-nuget 0.239.0 → 0.240.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/lib/dependabot/nuget/cache_manager.rb +2 -0
- data/lib/dependabot/nuget/file_fetcher.rb +51 -40
- data/lib/dependabot/nuget/file_parser/packages_config_parser.rb +0 -6
- data/lib/dependabot/nuget/file_parser/project_file_parser.rb +7 -22
- data/lib/dependabot/nuget/file_parser.rb +1 -1
- data/lib/dependabot/nuget/file_updater.rb +6 -2
- data/lib/dependabot/nuget/native_helpers.rb +7 -4
- data/lib/dependabot/nuget/nuget_client.rb +99 -0
- data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +71 -0
- data/lib/dependabot/nuget/requirement.rb +1 -1
- data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +2 -2
- data/lib/dependabot/nuget/update_checker/dependency_finder.rb +2 -2
- data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +1 -29
- data/lib/dependabot/nuget/update_checker/property_updater.rb +2 -2
- data/lib/dependabot/nuget/update_checker/repository_finder.rb +39 -8
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +2 -2
- data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +2 -2
- data/lib/dependabot/nuget/update_checker/tfm_finder.rb +2 -2
- data/lib/dependabot/nuget/update_checker/version_finder.rb +4 -42
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d8152c074be84d639b86fe67da074f558ca1509102a5a1e9e97c3411178a747
|
4
|
+
data.tar.gz: 6562552b5b89ddfc8c521aeb7a52cf17e2d918c230439f70281663d5e8e45811
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d91dec9cd6d5db739507bfc91d6454b6f21426a60a2086bd7b944922d4fa123886dbb1037a94b712471deeb89d175c1b0f10a2b84aeb7f6810f3aeddb92eecb
|
7
|
+
data.tar.gz: 7dbe0cacc3ffaa2d9290e09da5026a94432b8f45b839c6db49905b40636188c0201b61f6650aa1a01fa36fe590672b3e0359b8d4139d1bfe26d98dac344b494a
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require "dependabot/file_fetchers"
|
5
5
|
require "dependabot/file_fetchers/base"
|
6
|
+
require "dependabot/nuget/cache_manager"
|
6
7
|
require "set"
|
7
8
|
require "sorbet-runtime"
|
8
9
|
|
@@ -23,7 +24,7 @@ module Dependabot
|
|
23
24
|
return true if filenames.any? { |f| f.match?("^src$") }
|
24
25
|
return true if filenames.any? { |f| f.end_with?(".proj") }
|
25
26
|
|
26
|
-
filenames.any? { |name| name.match?(
|
27
|
+
filenames.any? { |name| name.match?(/\.[a-z]{2}proj$/) }
|
27
28
|
end
|
28
29
|
|
29
30
|
def self.required_files_message
|
@@ -219,29 +220,32 @@ module Dependabot
|
|
219
220
|
def nuget_config_files
|
220
221
|
return @nuget_config_files if @nuget_config_files
|
221
222
|
|
222
|
-
@nuget_config_files = [
|
223
|
-
|
224
|
-
|
225
|
-
candidate_paths.each do |dir|
|
226
|
-
search_in_directory_and_parents(dir, visited_directories)
|
227
|
-
end
|
223
|
+
@nuget_config_files = [*project_files.map do |f|
|
224
|
+
named_file_up_tree_from_project_file(f, "nuget.config")
|
225
|
+
end].compact.uniq
|
228
226
|
@nuget_config_files
|
229
227
|
end
|
230
228
|
|
231
|
-
def
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
229
|
+
def named_file_up_tree_from_project_file(project_file, expected_file_name)
|
230
|
+
found_expected_file = nil
|
231
|
+
directory_path = Pathname.new(directory)
|
232
|
+
full_project_dir = Pathname.new(project_file.directory).join(project_file.name).dirname
|
233
|
+
full_project_dir.ascend.each do |base|
|
234
|
+
break if found_expected_file
|
235
|
+
|
236
|
+
candidate_file_path = Pathname.new(base).join(expected_file_name).cleanpath.to_path
|
237
|
+
candidate_directory = Pathname.new(File.dirname(candidate_file_path))
|
238
|
+
relative_candidate_directory = candidate_directory.relative_path_from(directory_path)
|
239
|
+
candidate_file = repo_contents(dir: relative_candidate_directory).find do |f|
|
240
|
+
f.name.casecmp?(expected_file_name)
|
241
|
+
end
|
242
|
+
if candidate_file
|
243
|
+
found_expected_file = fetch_file_from_host(File.join(relative_candidate_directory,
|
244
|
+
candidate_file.name))
|
242
245
|
end
|
243
|
-
dir = File.dirname(dir)
|
244
246
|
end
|
247
|
+
|
248
|
+
found_expected_file
|
245
249
|
end
|
246
250
|
|
247
251
|
def global_json
|
@@ -280,27 +284,34 @@ module Dependabot
|
|
280
284
|
end
|
281
285
|
|
282
286
|
def fetch_imported_property_files(file:, previously_fetched_files:)
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
file
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
287
|
+
file_id = file.directory + "/" + file.name
|
288
|
+
@fetched_files ||= {}
|
289
|
+
if @fetched_files[file_id]
|
290
|
+
@fetched_files[file_id]
|
291
|
+
else
|
292
|
+
paths =
|
293
|
+
ImportPathsFinder.new(project_file: file).import_paths +
|
294
|
+
ImportPathsFinder.new(project_file: file).project_reference_paths +
|
295
|
+
ImportPathsFinder.new(project_file: file).project_file_paths
|
296
|
+
|
297
|
+
paths.flat_map do |path|
|
298
|
+
next if previously_fetched_files.map(&:name).include?(path)
|
299
|
+
next if file.name == path
|
300
|
+
next if path.include?("$(")
|
301
|
+
|
302
|
+
fetched_file = fetch_file_from_host(path)
|
303
|
+
grandchild_property_files = fetch_imported_property_files(
|
304
|
+
file: fetched_file,
|
305
|
+
previously_fetched_files: previously_fetched_files + [file]
|
306
|
+
)
|
307
|
+
@fetched_files[file_id] = [fetched_file, *grandchild_property_files]
|
308
|
+
@fetched_files[file_id]
|
309
|
+
rescue Dependabot::DependencyFileNotFound
|
310
|
+
# Don't worry about missing files too much for now (at least
|
311
|
+
# until we start resolving properties)
|
312
|
+
nil
|
313
|
+
end.compact
|
314
|
+
end
|
304
315
|
end
|
305
316
|
end
|
306
317
|
end
|
@@ -26,16 +26,10 @@ module Dependabot
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def dependency_set
|
29
|
-
return parse_dependencies if CacheManager.caching_disabled?
|
30
|
-
|
31
29
|
key = "#{packages_config.name.downcase}::#{packages_config.content.hash}"
|
32
30
|
cache = PackagesConfigParser.dependency_set_cache
|
33
31
|
|
34
32
|
cache[key] ||= parse_dependencies
|
35
|
-
|
36
|
-
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
37
|
-
dependency_set += cache[key]
|
38
|
-
dependency_set
|
39
33
|
end
|
40
34
|
|
41
35
|
private
|
@@ -7,13 +7,13 @@ require "dependabot/dependency"
|
|
7
7
|
require "dependabot/nuget/file_parser"
|
8
8
|
require "dependabot/nuget/update_checker"
|
9
9
|
require "dependabot/nuget/cache_manager"
|
10
|
+
require "dependabot/nuget/nuget_client"
|
10
11
|
|
11
12
|
# For details on how dotnet handles version constraints, see:
|
12
13
|
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning
|
13
14
|
module Dependabot
|
14
15
|
module Nuget
|
15
16
|
class FileParser
|
16
|
-
# rubocop:disable Metrics/ClassLength
|
17
17
|
class ProjectFileParser
|
18
18
|
require "dependabot/file_parsers/base/dependency_set"
|
19
19
|
require_relative "property_value_finder"
|
@@ -50,16 +50,10 @@ module Dependabot
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def dependency_set(project_file:)
|
53
|
-
return parse_dependencies(project_file) if CacheManager.caching_disabled?
|
54
|
-
|
55
53
|
key = "#{project_file.name.downcase}::#{project_file.content.hash}"
|
56
54
|
cache = ProjectFileParser.dependency_set_cache
|
57
55
|
|
58
56
|
cache[key] ||= parse_dependencies(project_file)
|
59
|
-
|
60
|
-
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
61
|
-
dependency_set += cache[key]
|
62
|
-
dependency_set
|
63
57
|
end
|
64
58
|
|
65
59
|
def target_frameworks(project_file:)
|
@@ -78,6 +72,10 @@ module Dependabot
|
|
78
72
|
["net#{value[1..-1].delete('.')}"]
|
79
73
|
end
|
80
74
|
|
75
|
+
def nuget_configs
|
76
|
+
dependency_files.select { |f| f.name.match?(%r{(^|/)nuget\.config$}i) }
|
77
|
+
end
|
78
|
+
|
81
79
|
private
|
82
80
|
|
83
81
|
attr_reader :dependency_files, :credentials
|
@@ -281,7 +279,6 @@ module Dependabot
|
|
281
279
|
end
|
282
280
|
|
283
281
|
def dependency_has_search_results?(dependency)
|
284
|
-
nuget_configs = dependency_files.select { |f| f.name.casecmp?("nuget.config") }
|
285
282
|
dependency_urls = UpdateChecker::RepositoryFinder.new(
|
286
283
|
dependency: dependency,
|
287
284
|
credentials: credentials,
|
@@ -307,16 +304,9 @@ module Dependabot
|
|
307
304
|
end
|
308
305
|
|
309
306
|
def dependency_url_has_matching_result_v3?(dependency_name, dependency_url)
|
310
|
-
|
311
|
-
auth_header = dependency_url.fetch(:auth_header)
|
312
|
-
response = execute_search_for_dependency_url(url, auth_header)
|
313
|
-
return false unless response.status == 200
|
314
|
-
|
315
|
-
body = JSON.parse(response.body)
|
316
|
-
data = body["data"]
|
317
|
-
return false unless data.length.positive?
|
307
|
+
versions = NugetClient.get_package_versions_v3(dependency_name, dependency_url)
|
318
308
|
|
319
|
-
|
309
|
+
versions != nil
|
320
310
|
end
|
321
311
|
|
322
312
|
def dependency_url_has_matching_result_v2?(dependency_name, dependency_url)
|
@@ -490,10 +480,6 @@ module Dependabot
|
|
490
480
|
end
|
491
481
|
end
|
492
482
|
|
493
|
-
def nuget_configs
|
494
|
-
dependency_files.select { |f| f.name.match?(/nuget\.config$/i) }
|
495
|
-
end
|
496
|
-
|
497
483
|
def global_json
|
498
484
|
dependency_files.find { |f| f.name.casecmp("global.json").zero? }
|
499
485
|
end
|
@@ -502,7 +488,6 @@ module Dependabot
|
|
502
488
|
dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json").zero? }
|
503
489
|
end
|
504
490
|
end
|
505
|
-
# rubocop:enable Metrics/ClassLength
|
506
491
|
end
|
507
492
|
end
|
508
493
|
end
|
@@ -62,7 +62,9 @@ module Dependabot
|
|
62
62
|
|
63
63
|
next unless project_dependencies.any? { |dep| dep.name.casecmp(dependency.name).zero? }
|
64
64
|
|
65
|
-
NativeHelpers.run_nuget_updater_tool(repo_contents_path, proj_path
|
65
|
+
NativeHelpers.run_nuget_updater_tool(repo_root: repo_contents_path, proj_path: proj_path,
|
66
|
+
dependency: dependency, is_transitive: !dependency.top_level?,
|
67
|
+
credentials: credentials)
|
66
68
|
update_ran = true
|
67
69
|
end
|
68
70
|
|
@@ -77,7 +79,9 @@ module Dependabot
|
|
77
79
|
project_file = project_files.first
|
78
80
|
proj_path = dependency_file_path(project_file)
|
79
81
|
|
80
|
-
NativeHelpers.run_nuget_updater_tool(repo_contents_path, proj_path
|
82
|
+
NativeHelpers.run_nuget_updater_tool(repo_root: repo_contents_path, proj_path: proj_path,
|
83
|
+
dependency: dependency, is_transitive: !dependency.top_level?,
|
84
|
+
credentials: credentials)
|
81
85
|
return true
|
82
86
|
end
|
83
87
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require_relative "nuget_config_credential_helpers"
|
5
|
+
|
4
6
|
module Dependabot
|
5
7
|
module Nuget
|
6
8
|
module NativeHelpers
|
@@ -46,7 +48,7 @@ module Dependabot
|
|
46
48
|
end
|
47
49
|
|
48
50
|
# rubocop:disable Metrics/MethodLength
|
49
|
-
def self.run_nuget_updater_tool(repo_root
|
51
|
+
def self.run_nuget_updater_tool(repo_root:, proj_path:, dependency:, is_transitive:, credentials:)
|
50
52
|
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
51
53
|
command = [
|
52
54
|
exe_path,
|
@@ -84,9 +86,10 @@ module Dependabot
|
|
84
86
|
|
85
87
|
puts "running NuGet updater:\n" + command
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
NuGetConfigCredentialHelpers.patch_nuget_config_for_action(credentials) do
|
90
|
+
output = SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
|
91
|
+
puts output
|
92
|
+
end
|
90
93
|
end
|
91
94
|
# rubocop:enable Metrics/MethodLength
|
92
95
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "dependabot/nuget/cache_manager"
|
5
|
+
require "dependabot/nuget/update_checker/repository_finder"
|
6
|
+
|
7
|
+
module Dependabot
|
8
|
+
module Nuget
|
9
|
+
class NugetClient
|
10
|
+
def self.get_package_versions_v3(dependency_name, repository_details)
|
11
|
+
# Use the registration URL if possible because it is fast and correct
|
12
|
+
if repository_details[:registration_url]
|
13
|
+
get_versions_from_registration_v3(repository_details)
|
14
|
+
# use the search API if not because it is slow but correct
|
15
|
+
elsif repository_details[:search_url]
|
16
|
+
get_versions_from_search_url_v3(repository_details, dependency_name)
|
17
|
+
# Otherwise, use the versions URL (fast but wrong because it includes unlisted versions)
|
18
|
+
elsif repository_details[:versions_url]
|
19
|
+
get_versions_from_versions_url_v3(repository_details)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private_class_method def self.get_versions_from_versions_url_v3(repository_details)
|
24
|
+
body = execute_search_for_dependency_url(repository_details[:versions_url], repository_details)
|
25
|
+
body&.fetch("versions")
|
26
|
+
end
|
27
|
+
|
28
|
+
private_class_method def self.get_versions_from_registration_v3(repository_details)
|
29
|
+
url = repository_details[:registration_url]
|
30
|
+
body = execute_search_for_dependency_url(url, repository_details)
|
31
|
+
|
32
|
+
return unless body
|
33
|
+
|
34
|
+
pages = body.fetch("items")
|
35
|
+
versions = Set.new
|
36
|
+
pages.each do |page|
|
37
|
+
items = page["items"]
|
38
|
+
if items
|
39
|
+
# inlined entries
|
40
|
+
items.each do |item|
|
41
|
+
catalog_entry = item["catalogEntry"]
|
42
|
+
if catalog_entry["listed"] == true
|
43
|
+
vers = catalog_entry["version"]
|
44
|
+
versions << vers
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
# paged entries
|
49
|
+
page_url = page["@id"]
|
50
|
+
page_body = execute_search_for_dependency_url(page_url, repository_details)
|
51
|
+
items = page_body.fetch("items")
|
52
|
+
items.each do |item|
|
53
|
+
catalog_entry = item.fetch("catalogEntry")
|
54
|
+
versions << catalog_entry.fetch("version") if catalog_entry["listed"] == true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
versions
|
60
|
+
end
|
61
|
+
|
62
|
+
private_class_method def self.get_versions_from_search_url_v3(repository_details, dependency_name)
|
63
|
+
search_url = repository_details[:search_url]
|
64
|
+
body = execute_search_for_dependency_url(search_url, repository_details)
|
65
|
+
|
66
|
+
body&.fetch("data")
|
67
|
+
&.find { |d| d.fetch("id").casecmp(dependency_name.downcase).zero? }
|
68
|
+
&.fetch("versions")
|
69
|
+
&.map { |d| d.fetch("version") }
|
70
|
+
end
|
71
|
+
|
72
|
+
private_class_method def self.execute_search_for_dependency_url(url, repository_details)
|
73
|
+
cache = CacheManager.cache("dependency_url_search_cache")
|
74
|
+
cache[url] ||= Dependabot::RegistryClient.get(
|
75
|
+
url: url,
|
76
|
+
headers: repository_details[:auth_header]
|
77
|
+
)
|
78
|
+
|
79
|
+
response = cache[url]
|
80
|
+
|
81
|
+
return unless response.status == 200
|
82
|
+
|
83
|
+
body = remove_wrapping_zero_width_chars(response.body)
|
84
|
+
JSON.parse(body)
|
85
|
+
rescue Excon::Error::Timeout, Excon::Error::Socket
|
86
|
+
repo_url = repository_details[:repository_url]
|
87
|
+
raise if repo_url == Dependabot::Nuget::UpdateChecker::RepositoryFinder::DEFAULT_REPOSITORY_URL
|
88
|
+
|
89
|
+
raise PrivateSourceTimedOut, repo_url
|
90
|
+
end
|
91
|
+
|
92
|
+
private_class_method def self.remove_wrapping_zero_width_chars(string)
|
93
|
+
string.force_encoding("UTF-8").encode
|
94
|
+
.gsub(/\A[\u200B-\u200D\uFEFF]/, "")
|
95
|
+
.gsub(/[\u200B-\u200D\uFEFF]\Z/, "")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Dependabot
|
5
|
+
module Nuget
|
6
|
+
module NuGetConfigCredentialHelpers
|
7
|
+
def self.user_nuget_config_path
|
8
|
+
home_directory = Dir.home
|
9
|
+
File.join(home_directory, ".nuget", "NuGet", "NuGet.Config")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.temporary_nuget_config_path
|
13
|
+
user_nuget_config_path + "_ORIGINAL"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.add_credentials_to_nuget_config(credentials)
|
17
|
+
return unless File.exist?(user_nuget_config_path)
|
18
|
+
|
19
|
+
nuget_credentials = credentials.select { |cred| cred["type"] == "nuget_feed" }
|
20
|
+
return if nuget_credentials.empty?
|
21
|
+
|
22
|
+
File.rename(user_nuget_config_path, temporary_nuget_config_path)
|
23
|
+
|
24
|
+
package_sources = []
|
25
|
+
package_source_credentials = []
|
26
|
+
nuget_credentials.each_with_index do |c, i|
|
27
|
+
source_name = "nuget_source_#{i + 1}"
|
28
|
+
package_sources << " <add key=\"#{source_name}\" value=\"#{c['url']}\" />"
|
29
|
+
next unless c["token"]
|
30
|
+
|
31
|
+
package_source_credentials << " <#{source_name}>"
|
32
|
+
package_source_credentials << " <add key=\"Username\" value=\"user\" />"
|
33
|
+
package_source_credentials << " <add key=\"ClearTextPassword\" value=\"#{c['token']}\" />"
|
34
|
+
package_source_credentials << " </#{source_name}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
nuget_config = <<~NUGET_XML
|
38
|
+
<?xml version="1.0" encoding="utf-8"?>
|
39
|
+
<configuration>
|
40
|
+
<packageSources>
|
41
|
+
#{package_sources.join("\n")}
|
42
|
+
</packageSources>
|
43
|
+
<packageSourceCredentials>
|
44
|
+
#{package_source_credentials.join("\n")}
|
45
|
+
</packageSourceCredentials>
|
46
|
+
</configuration>
|
47
|
+
NUGET_XML
|
48
|
+
File.write(user_nuget_config_path, nuget_config)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.restore_user_nuget_config
|
52
|
+
return unless File.exist?(temporary_nuget_config_path)
|
53
|
+
|
54
|
+
File.delete(user_nuget_config_path)
|
55
|
+
File.rename(temporary_nuget_config_path, user_nuget_config_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
# rubocop:disable Lint/SuppressedException
|
59
|
+
def self.patch_nuget_config_for_action(credentials, &_block)
|
60
|
+
add_credentials_to_nuget_config(credentials)
|
61
|
+
begin
|
62
|
+
yield
|
63
|
+
rescue StandardError
|
64
|
+
ensure
|
65
|
+
restore_user_nuget_config
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# rubocop:enable Lint/SuppressedException
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -22,7 +22,7 @@ module Dependabot
|
|
22
22
|
|
23
23
|
return DefaultRequirement if matches[1] == ">=" && matches[2] == "0"
|
24
24
|
|
25
|
-
[matches[1] || "=", Nuget::Version.new(matches[2])]
|
25
|
+
[matches[1] || "=", Nuget::Version.new(T.must(matches[2]))]
|
26
26
|
end
|
27
27
|
|
28
28
|
# For consistency with other languages, we define a requirements array.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "dependabot/
|
4
|
+
require "dependabot/update_checkers/base"
|
5
5
|
|
6
6
|
module Dependabot
|
7
7
|
module Nuget
|
8
|
-
class UpdateChecker
|
8
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
9
9
|
class CompatibilityChecker
|
10
10
|
require_relative "nuspec_fetcher"
|
11
11
|
require_relative "nupkg_fetcher"
|
@@ -4,12 +4,12 @@
|
|
4
4
|
require "nokogiri"
|
5
5
|
require "zip"
|
6
6
|
require "stringio"
|
7
|
-
require "dependabot/
|
7
|
+
require "dependabot/update_checkers/base"
|
8
8
|
require "dependabot/nuget/version"
|
9
9
|
|
10
10
|
module Dependabot
|
11
11
|
module Nuget
|
12
|
-
class UpdateChecker
|
12
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
13
13
|
class DependencyFinder
|
14
14
|
require_relative "requirements_updater"
|
15
15
|
require_relative "nuspec_fetcher"
|
@@ -23,10 +23,7 @@ module Dependabot
|
|
23
23
|
feed_url = repository_details[:repository_url]
|
24
24
|
repository_type = repository_details[:repository_type]
|
25
25
|
|
26
|
-
|
27
|
-
package_url = if azure_devops_match
|
28
|
-
get_azure_package_url(azure_devops_match, package_id, package_version)
|
29
|
-
elsif repository_type == "v2"
|
26
|
+
package_url = if repository_type == "v2"
|
30
27
|
get_nuget_v2_package_url(feed_url, package_id, package_version)
|
31
28
|
elsif repository_type == "v3"
|
32
29
|
get_nuget_v3_package_url(repository_details, package_id, package_version)
|
@@ -45,31 +42,6 @@ module Dependabot
|
|
45
42
|
fetch_stream(package_url, auth_header)
|
46
43
|
end
|
47
44
|
|
48
|
-
def self.try_match_azure_url(feed_url)
|
49
|
-
# if url is azure devops
|
50
|
-
azure_devops_regexs = [
|
51
|
-
%r{https://pkgs\.dev\.azure\.com/(?<organization>[^/]+)/(?<project>[^/]+)/_packaging/(?<feedId>[^/]+)/nuget/v3/index\.json},
|
52
|
-
%r{https://pkgs\.dev\.azure\.com/(?<organization>[^/]+)/_packaging/(?<feedId>[^/]+)/nuget/v3/index\.json(?<project>)},
|
53
|
-
%r{https://(?<organization>[^\.\/]+)\.pkgs\.visualstudio\.com/_packaging/(?<feedId>[^/]+)/nuget/v3/index\.json(?<project>)}
|
54
|
-
]
|
55
|
-
regex = azure_devops_regexs.find { |reg| reg.match(feed_url) }
|
56
|
-
return unless regex
|
57
|
-
|
58
|
-
regex.match(feed_url)
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.get_azure_package_url(azure_devops_match, package_id, package_version)
|
62
|
-
organization = azure_devops_match[:organization]
|
63
|
-
project = azure_devops_match[:project]
|
64
|
-
feed_id = azure_devops_match[:feedId]
|
65
|
-
|
66
|
-
if project.empty?
|
67
|
-
"https://pkgs.dev.azure.com/#{organization}/_apis/packaging/feeds/#{feed_id}/nuget/packages/#{package_id}/versions/#{package_version}/content?sourceProtocolVersion=nuget&api-version=7.0-preview"
|
68
|
-
else
|
69
|
-
"https://pkgs.dev.azure.com/#{organization}/#{project}/_apis/packaging/feeds/#{feed_id}/nuget/packages/#{package_id}/versions/#{package_version}/content?sourceProtocolVersion=nuget&api-version=7.0-preview"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
45
|
def self.get_nuget_v3_package_url(repository_details, package_id, package_version)
|
74
46
|
base_url = repository_details[:base_url].delete_suffix("/")
|
75
47
|
package_id_downcased = package_id.downcase
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "dependabot/update_checkers/base"
|
4
5
|
require "dependabot/nuget/file_parser"
|
5
|
-
require "dependabot/nuget/update_checker"
|
6
6
|
|
7
7
|
module Dependabot
|
8
8
|
module Nuget
|
9
|
-
class UpdateChecker
|
9
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
10
10
|
class PropertyUpdater
|
11
11
|
require_relative "version_finder"
|
12
12
|
require_relative "requirements_updater"
|
@@ -4,12 +4,13 @@
|
|
4
4
|
require "excon"
|
5
5
|
require "nokogiri"
|
6
6
|
require "dependabot/errors"
|
7
|
-
require "dependabot/
|
7
|
+
require "dependabot/update_checkers/base"
|
8
8
|
require "dependabot/registry_client"
|
9
|
+
require "dependabot/nuget/cache_manager"
|
9
10
|
|
10
11
|
module Dependabot
|
11
12
|
module Nuget
|
12
|
-
class UpdateChecker
|
13
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
13
14
|
class RepositoryFinder
|
14
15
|
DEFAULT_REPOSITORY_URL = "https://api.nuget.org/v3/index.json"
|
15
16
|
DEFAULT_REPOSITORY_API_KEY = "nuget.org"
|
@@ -27,6 +28,7 @@ module Dependabot
|
|
27
28
|
def self.get_default_repository_details(dependency_name)
|
28
29
|
{
|
29
30
|
base_url: "https://api.nuget.org/v3-flatcontainer/",
|
31
|
+
registration_url: "https://api.nuget.org/v3/registration5-gz-semver2/#{dependency_name.downcase}/index.json",
|
30
32
|
repository_url: DEFAULT_REPOSITORY_URL,
|
31
33
|
versions_url: "https://api.nuget.org/v3-flatcontainer/" \
|
32
34
|
"#{dependency_name.downcase}/index.json",
|
@@ -60,9 +62,11 @@ module Dependabot
|
|
60
62
|
return unless response.status == 200
|
61
63
|
|
62
64
|
body = remove_wrapping_zero_width_chars(response.body)
|
63
|
-
|
65
|
+
parsed_json = JSON.parse(body)
|
66
|
+
base_url = base_url_from_v3_metadata(parsed_json)
|
64
67
|
resolved_base_url = base_url || repo_details.fetch(:url).gsub("/index.json", "-flatcontainer")
|
65
|
-
search_url = search_url_from_v3_metadata(
|
68
|
+
search_url = search_url_from_v3_metadata(parsed_json)
|
69
|
+
registration_url = registration_url_from_v3_metadata(parsed_json)
|
66
70
|
|
67
71
|
details = {
|
68
72
|
base_url: resolved_base_url,
|
@@ -78,6 +82,11 @@ module Dependabot
|
|
78
82
|
details[:search_url] =
|
79
83
|
search_url + "?q=#{dependency.name.downcase}&prerelease=true&semVerLevel=2.0.0"
|
80
84
|
end
|
85
|
+
|
86
|
+
if registration_url
|
87
|
+
details[:registration_url] = File.join(registration_url, dependency.name.downcase, "index.json")
|
88
|
+
end
|
89
|
+
|
81
90
|
details
|
82
91
|
rescue JSON::ParserError
|
83
92
|
build_v2_url(response, repo_details)
|
@@ -86,10 +95,18 @@ module Dependabot
|
|
86
95
|
end
|
87
96
|
|
88
97
|
def get_repo_metadata(repo_details)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
98
|
+
url = repo_details.fetch(:url)
|
99
|
+
cache = CacheManager.cache("repo_finder_metadatacache")
|
100
|
+
if cache[url]
|
101
|
+
cache[url]
|
102
|
+
else
|
103
|
+
result = Dependabot::RegistryClient.get(
|
104
|
+
url: url,
|
105
|
+
headers: auth_header_for_token(repo_details.fetch(:token))
|
106
|
+
)
|
107
|
+
cache[url] = result
|
108
|
+
result
|
109
|
+
end
|
93
110
|
end
|
94
111
|
|
95
112
|
def base_url_from_v3_metadata(metadata)
|
@@ -99,6 +116,20 @@ module Dependabot
|
|
99
116
|
&.fetch("@id")
|
100
117
|
end
|
101
118
|
|
119
|
+
def registration_url_from_v3_metadata(metadata)
|
120
|
+
allowed_registration_types = %w(
|
121
|
+
RegistrationsBaseUrl
|
122
|
+
RegistrationsBaseUrl/3.0.0-beta
|
123
|
+
RegistrationsBaseUrl/3.0.0-rc
|
124
|
+
RegistrationsBaseUrl/3.4.0
|
125
|
+
RegistrationsBaseUrl/3.6.0
|
126
|
+
)
|
127
|
+
metadata
|
128
|
+
.fetch("resources", [])
|
129
|
+
.find { |r| allowed_registration_types.find { |s| r.fetch("@type") == s } }
|
130
|
+
&.fetch("@id")
|
131
|
+
end
|
132
|
+
|
102
133
|
def search_url_from_v3_metadata(metadata)
|
103
134
|
# allowable values from here: https://learn.microsoft.com/en-us/nuget/api/search-query-service-resource#versioning
|
104
135
|
allowed_search_types = %w(
|
@@ -6,12 +6,12 @@
|
|
6
6
|
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning #
|
7
7
|
#######################################################################
|
8
8
|
|
9
|
-
require "dependabot/
|
9
|
+
require "dependabot/update_checkers/base"
|
10
10
|
require "dependabot/nuget/version"
|
11
11
|
|
12
12
|
module Dependabot
|
13
13
|
module Nuget
|
14
|
-
class UpdateChecker
|
14
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
15
15
|
class RequirementsUpdater
|
16
16
|
def initialize(requirements:, latest_version:, source_details:)
|
17
17
|
@requirements = requirements
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "dependabot/update_checkers/base"
|
4
5
|
require "dependabot/nuget/version"
|
5
6
|
require "dependabot/nuget/requirement"
|
6
7
|
require "dependabot/nuget/native_helpers"
|
7
|
-
require "dependabot/nuget/update_checker"
|
8
8
|
require "dependabot/shared_helpers"
|
9
9
|
|
10
10
|
module Dependabot
|
11
11
|
module Nuget
|
12
|
-
class UpdateChecker
|
12
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
13
13
|
class TfmComparer
|
14
14
|
def self.are_frameworks_compatible?(project_tfms, package_tfms)
|
15
15
|
return false if package_tfms.empty?
|
@@ -4,15 +4,15 @@
|
|
4
4
|
require "excon"
|
5
5
|
require "nokogiri"
|
6
6
|
|
7
|
+
require "dependabot/update_checkers/base"
|
7
8
|
require "dependabot/nuget/version"
|
8
9
|
require "dependabot/nuget/requirement"
|
9
10
|
require "dependabot/nuget/native_helpers"
|
10
|
-
require "dependabot/nuget/update_checker"
|
11
11
|
require "dependabot/shared_helpers"
|
12
12
|
|
13
13
|
module Dependabot
|
14
14
|
module Nuget
|
15
|
-
class UpdateChecker
|
15
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
16
16
|
class TfmFinder
|
17
17
|
require "dependabot/nuget/file_parser/packages_config_parser"
|
18
18
|
require "dependabot/nuget/file_parser/project_file_parser"
|
@@ -3,12 +3,13 @@
|
|
3
3
|
|
4
4
|
require "dependabot/nuget/version"
|
5
5
|
require "dependabot/nuget/requirement"
|
6
|
+
require "dependabot/update_checkers/base"
|
6
7
|
require "dependabot/update_checkers/version_filters"
|
7
|
-
require "dependabot/nuget/
|
8
|
+
require "dependabot/nuget/nuget_client"
|
8
9
|
|
9
10
|
module Dependabot
|
10
11
|
module Nuget
|
11
|
-
class UpdateChecker
|
12
|
+
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
12
13
|
class VersionFinder
|
13
14
|
require_relative "compatibility_checker"
|
14
15
|
require_relative "repository_finder"
|
@@ -294,40 +295,7 @@ module Dependabot
|
|
294
295
|
end
|
295
296
|
|
296
297
|
def versions_for_v3_repository(repository_details)
|
297
|
-
|
298
|
-
# (since it will exclude unlisted versions)
|
299
|
-
if repository_details[:search_url]
|
300
|
-
fetch_versions_from_search_url(repository_details)
|
301
|
-
# Otherwise, use the versions URL
|
302
|
-
elsif repository_details[:versions_url]
|
303
|
-
response = Dependabot::RegistryClient.get(
|
304
|
-
url: repository_details[:versions_url],
|
305
|
-
headers: repository_details[:auth_header]
|
306
|
-
)
|
307
|
-
return unless response.status == 200
|
308
|
-
|
309
|
-
body = remove_wrapping_zero_width_chars(response.body)
|
310
|
-
JSON.parse(body).fetch("versions")
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def fetch_versions_from_search_url(repository_details)
|
315
|
-
response = Dependabot::RegistryClient.get(
|
316
|
-
url: repository_details[:search_url],
|
317
|
-
headers: repository_details[:auth_header]
|
318
|
-
)
|
319
|
-
return unless response.status == 200
|
320
|
-
|
321
|
-
body = remove_wrapping_zero_width_chars(response.body)
|
322
|
-
JSON.parse(body).fetch("data")
|
323
|
-
.find { |d| d.fetch("id").casecmp(sanitized_name).zero? }
|
324
|
-
&.fetch("versions")
|
325
|
-
&.map { |d| d.fetch("version") }
|
326
|
-
rescue Excon::Error::Timeout, Excon::Error::Socket
|
327
|
-
repo_url = repository_details[:repository_url]
|
328
|
-
raise if repo_url == RepositoryFinder::DEFAULT_REPOSITORY_URL
|
329
|
-
|
330
|
-
raise PrivateSourceTimedOut, repo_url
|
298
|
+
NugetClient.get_package_versions_v3(dependency.name, repository_details)
|
331
299
|
end
|
332
300
|
|
333
301
|
def dependency_urls
|
@@ -356,12 +324,6 @@ module Dependabot
|
|
356
324
|
dependency.requirement_class
|
357
325
|
end
|
358
326
|
|
359
|
-
def remove_wrapping_zero_width_chars(string)
|
360
|
-
string.force_encoding("UTF-8").encode
|
361
|
-
.gsub(/\A[\u200B-\u200D\uFEFF]/, "")
|
362
|
-
.gsub(/[\u200B-\u200D\uFEFF]\Z/, "")
|
363
|
-
end
|
364
|
-
|
365
327
|
def excon_options
|
366
328
|
# For large JSON files we sometimes need a little longer than for
|
367
329
|
# other languages. For example, see:
|
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.
|
4
|
+
version: 0.240.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-12 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.
|
19
|
+
version: 0.240.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.
|
26
|
+
version: 0.240.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,6 +226,20 @@ dependencies:
|
|
226
226
|
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '3.18'
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: webrick
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '1.7'
|
236
|
+
type: :development
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '1.7'
|
229
243
|
description: Dependabot-Nuget provides support for bumping .NET (NuGet) packages via
|
230
244
|
Dependabot. If you want support for multiple package managers, you probably want
|
231
245
|
the meta-gem dependabot-omnibus.
|
@@ -249,6 +263,8 @@ files:
|
|
249
263
|
- lib/dependabot/nuget/file_updater/property_value_updater.rb
|
250
264
|
- lib/dependabot/nuget/metadata_finder.rb
|
251
265
|
- lib/dependabot/nuget/native_helpers.rb
|
266
|
+
- lib/dependabot/nuget/nuget_client.rb
|
267
|
+
- lib/dependabot/nuget/nuget_config_credential_helpers.rb
|
252
268
|
- lib/dependabot/nuget/requirement.rb
|
253
269
|
- lib/dependabot/nuget/update_checker.rb
|
254
270
|
- lib/dependabot/nuget/update_checker/compatibility_checker.rb
|
@@ -267,7 +283,7 @@ licenses:
|
|
267
283
|
- Nonstandard
|
268
284
|
metadata:
|
269
285
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
270
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
286
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.240.0
|
271
287
|
post_install_message:
|
272
288
|
rdoc_options: []
|
273
289
|
require_paths:
|