dependabot-nuget 0.322.2 → 0.325.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/Program.cs +0 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +1 -31
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +0 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyInfo.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +64 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencySolver/MSBuildDependencySolver.cs +10 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +31 -41
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Cooldown.cs +83 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +9 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGenerator.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +8 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +79 -67
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +10 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +245 -125
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +4 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +4 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +14 -31
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +3 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +12 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/XmlExtensions.cs +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +78 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +126 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +14 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +2 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/CooldownTests.cs +99 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +168 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGeneratorTests.cs +71 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +71 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +70 -39
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +43 -30
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +76 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +0 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +11 -27
- data/lib/dependabot/nuget.rb +3 -11
- metadata +8 -54
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +0 -49
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +0 -60
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +0 -35
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +0 -58
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +0 -380
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +0 -557
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.FrameworkCheck.cs +0 -37
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +0 -226
- data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +0 -65
- data/lib/dependabot/nuget/analysis/dependency_analysis.rb +0 -66
- data/lib/dependabot/nuget/cache_manager.rb +0 -29
- data/lib/dependabot/nuget/discovery/dependency_details.rb +0 -102
- data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +0 -122
- data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +0 -266
- data/lib/dependabot/nuget/discovery/evaluation_details.rb +0 -63
- data/lib/dependabot/nuget/discovery/project_discovery.rb +0 -104
- data/lib/dependabot/nuget/discovery/property_details.rb +0 -43
- data/lib/dependabot/nuget/discovery/workspace_discovery.rb +0 -61
- data/lib/dependabot/nuget/file_fetcher.rb +0 -46
- data/lib/dependabot/nuget/file_parser.rb +0 -153
- data/lib/dependabot/nuget/file_updater.rb +0 -256
- data/lib/dependabot/nuget/language.rb +0 -98
- data/lib/dependabot/nuget/metadata_finder.rb +0 -197
- data/lib/dependabot/nuget/native_helpers.rb +0 -364
- data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +0 -88
- data/lib/dependabot/nuget/package_manager.rb +0 -51
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +0 -105
- data/lib/dependabot/nuget/update_checker.rb +0 -210
@@ -1,197 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "nokogiri"
|
5
|
-
require "sorbet-runtime"
|
6
|
-
require "dependabot/metadata_finders"
|
7
|
-
require "dependabot/metadata_finders/base"
|
8
|
-
require "dependabot/registry_client"
|
9
|
-
|
10
|
-
module Dependabot
|
11
|
-
module Nuget
|
12
|
-
class MetadataFinder < Dependabot::MetadataFinders::Base
|
13
|
-
extend T::Sig
|
14
|
-
|
15
|
-
sig do
|
16
|
-
override
|
17
|
-
.params(
|
18
|
-
dependency: Dependabot::Dependency,
|
19
|
-
credentials: T::Array[Dependabot::Credential]
|
20
|
-
)
|
21
|
-
.void
|
22
|
-
end
|
23
|
-
def initialize(dependency:, credentials:)
|
24
|
-
@dependency_nuspec_file = T.let(nil, T.nilable(Nokogiri::XML::Document))
|
25
|
-
|
26
|
-
super
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
sig { override.returns(T.nilable(Dependabot::Source)) }
|
32
|
-
def look_up_source
|
33
|
-
return Source.from_url(dependency_source_url) if dependency_source_url
|
34
|
-
|
35
|
-
if dependency_nuspec_file
|
36
|
-
src_repo = look_up_source_in_nuspec(T.must(dependency_nuspec_file))
|
37
|
-
return src_repo if src_repo
|
38
|
-
end
|
39
|
-
|
40
|
-
# Fallback to getting source from the search result's projectUrl or licenseUrl.
|
41
|
-
# GitHub Packages doesn't support getting the `.nuspec`, switch to getting
|
42
|
-
# that instead once it is supported.
|
43
|
-
src_repo_from_project
|
44
|
-
rescue StandardError
|
45
|
-
# At this point in the process the PR is ready to be posted, we tried to gather commit
|
46
|
-
# and release notes, but have encountered an exception. So let's eat it since it's
|
47
|
-
# better to have a PR with no info than error out.
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
|
51
|
-
sig { returns(T.nilable(Dependabot::Source)) }
|
52
|
-
def src_repo_from_project
|
53
|
-
source = dependency.requirements.find { |r| r.fetch(:source) }&.fetch(:source)
|
54
|
-
return unless source
|
55
|
-
|
56
|
-
# Query the service index e.g. https://nuget.pkg.github.com/ORG/index.json
|
57
|
-
response = Dependabot::RegistryClient.get(
|
58
|
-
url: source.fetch(:url),
|
59
|
-
headers: { **auth_header, "Accept" => "application/json" }
|
60
|
-
)
|
61
|
-
return unless response.status == 200
|
62
|
-
|
63
|
-
# Extract the query url e.g. https://nuget.pkg.github.com/ORG/query
|
64
|
-
search_base = extract_search_url(response.body)
|
65
|
-
return unless search_base
|
66
|
-
|
67
|
-
response = Dependabot::RegistryClient.get(
|
68
|
-
url: search_base + "?q=#{dependency.name.downcase}&prerelease=true&semVerLevel=2.0.0",
|
69
|
-
headers: { **auth_header, "Accept" => "application/json" }
|
70
|
-
)
|
71
|
-
return unless response.status == 200
|
72
|
-
|
73
|
-
# Find a projectUrl or licenseUrl that look like a source URL
|
74
|
-
extract_source_repo(response.body)
|
75
|
-
rescue JSON::ParserError
|
76
|
-
# Ignored, this is expected for some registries that don't handle these request.
|
77
|
-
end
|
78
|
-
|
79
|
-
sig { params(body: String).returns(T.nilable(String)) }
|
80
|
-
def extract_search_url(body)
|
81
|
-
JSON.parse(body)
|
82
|
-
.fetch("resources", [])
|
83
|
-
.find { |r| r.fetch("@type") == "SearchQueryService" }
|
84
|
-
&.fetch("@id")
|
85
|
-
end
|
86
|
-
|
87
|
-
sig { params(body: String).returns(T.nilable(Dependabot::Source)) }
|
88
|
-
def extract_source_repo(body)
|
89
|
-
JSON.parse(body).fetch("data", []).each do |search_result|
|
90
|
-
next unless search_result["id"].casecmp(dependency.name).zero?
|
91
|
-
|
92
|
-
if search_result.key?("projectUrl")
|
93
|
-
source = Source.from_url(search_result.fetch("projectUrl"))
|
94
|
-
return source if source
|
95
|
-
end
|
96
|
-
if search_result.key?("licenseUrl")
|
97
|
-
source = Source.from_url(search_result.fetch("licenseUrl"))
|
98
|
-
return source if source
|
99
|
-
end
|
100
|
-
end
|
101
|
-
# failed to find a source URL
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
|
105
|
-
sig { params(nuspec: Nokogiri::XML::Document).returns(T.nilable(Dependabot::Source)) }
|
106
|
-
def look_up_source_in_nuspec(nuspec)
|
107
|
-
potential_source_urls = [
|
108
|
-
nuspec.at_css("package > metadata > repository")
|
109
|
-
&.attribute("url")&.value,
|
110
|
-
nuspec.at_css("package > metadata > repository > url")&.content,
|
111
|
-
nuspec.at_css("package > metadata > projectUrl")&.content,
|
112
|
-
nuspec.at_css("package > metadata > licenseUrl")&.content
|
113
|
-
].compact
|
114
|
-
|
115
|
-
source_url = potential_source_urls.find { |url| Source.from_url(url) }
|
116
|
-
source_url ||= source_from_anywhere_in_nuspec(nuspec)
|
117
|
-
|
118
|
-
Source.from_url(source_url)
|
119
|
-
end
|
120
|
-
|
121
|
-
sig { params(nuspec: Nokogiri::XML::Document).returns(T.nilable(String)) }
|
122
|
-
def source_from_anywhere_in_nuspec(nuspec)
|
123
|
-
github_urls = []
|
124
|
-
nuspec.to_s.force_encoding(Encoding::UTF_8)
|
125
|
-
.scan(Source::SOURCE_REGEX) do
|
126
|
-
github_urls << Regexp.last_match.to_s
|
127
|
-
end
|
128
|
-
|
129
|
-
github_urls.find do |url|
|
130
|
-
repo = T.must(Source.from_url(url)).repo
|
131
|
-
repo.downcase.end_with?(dependency.name.downcase)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
sig { returns(T.nilable(Nokogiri::XML::Document)) }
|
136
|
-
def dependency_nuspec_file
|
137
|
-
return @dependency_nuspec_file unless @dependency_nuspec_file.nil?
|
138
|
-
|
139
|
-
return if dependency_nuspec_url.nil?
|
140
|
-
|
141
|
-
response = Dependabot::RegistryClient.get(
|
142
|
-
url: T.must(dependency_nuspec_url),
|
143
|
-
headers: auth_header
|
144
|
-
)
|
145
|
-
|
146
|
-
@dependency_nuspec_file = Nokogiri::XML(response.body)
|
147
|
-
end
|
148
|
-
|
149
|
-
sig { returns(T.nilable(String)) }
|
150
|
-
def dependency_nuspec_url
|
151
|
-
source = dependency.requirements
|
152
|
-
.find { |r| r.fetch(:source) }&.fetch(:source)
|
153
|
-
|
154
|
-
source.fetch(:nuspec_url) if source&.key?(:nuspec_url)
|
155
|
-
end
|
156
|
-
|
157
|
-
sig { returns(T.nilable(String)) }
|
158
|
-
def dependency_source_url
|
159
|
-
source = dependency.requirements
|
160
|
-
.find { |r| r.fetch(:source) }&.fetch(:source)
|
161
|
-
|
162
|
-
return unless source
|
163
|
-
return source.fetch(:source_url) if source.key?(:source_url)
|
164
|
-
|
165
|
-
source.fetch("source_url")
|
166
|
-
end
|
167
|
-
|
168
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
169
|
-
sig { returns(T::Hash[String, String]) }
|
170
|
-
def auth_header
|
171
|
-
source = dependency.requirements
|
172
|
-
.find { |r| r.fetch(:source) }&.fetch(:source)
|
173
|
-
url = source&.fetch(:url, nil) || source&.fetch("url")
|
174
|
-
|
175
|
-
token = credentials
|
176
|
-
.select { |cred| cred["type"] == "nuget_feed" }
|
177
|
-
.find { |cred| cred["url"] == url }
|
178
|
-
&.fetch("token", nil)
|
179
|
-
|
180
|
-
return {} unless token
|
181
|
-
|
182
|
-
if token.include?(":")
|
183
|
-
encoded_token = Base64.encode64(token).delete("\n")
|
184
|
-
{ "Authorization" => "Basic #{encoded_token}" }
|
185
|
-
elsif Base64.decode64(token).ascii_only? &&
|
186
|
-
Base64.decode64(token).include?(":")
|
187
|
-
{ "Authorization" => "Basic #{token.delete("\n")}" }
|
188
|
-
else
|
189
|
-
{ "Authorization" => "Bearer #{token}" }
|
190
|
-
end
|
191
|
-
end
|
192
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
Dependabot::MetadataFinders.register("nuget", Dependabot::Nuget::MetadataFinder)
|
@@ -1,364 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "shellwords"
|
5
|
-
require "sorbet-runtime"
|
6
|
-
|
7
|
-
require_relative "nuget_config_credential_helpers"
|
8
|
-
|
9
|
-
module Dependabot
|
10
|
-
module Nuget
|
11
|
-
module NativeHelpers
|
12
|
-
extend T::Sig
|
13
|
-
|
14
|
-
sig { returns(String) }
|
15
|
-
def self.job_id
|
16
|
-
ENV.fetch("DEPENDABOT_JOB_ID")
|
17
|
-
end
|
18
|
-
|
19
|
-
sig { returns(String) }
|
20
|
-
def self.native_helpers_root
|
21
|
-
helpers_root = ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", nil)
|
22
|
-
return File.join(helpers_root, "nuget") unless helpers_root.nil?
|
23
|
-
|
24
|
-
File.expand_path("../../../helpers", __dir__)
|
25
|
-
end
|
26
|
-
|
27
|
-
sig { params(project_tfms: T::Array[String], package_tfms: T::Array[String]).returns(T::Boolean) }
|
28
|
-
def self.run_nuget_framework_check(project_tfms, package_tfms)
|
29
|
-
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
30
|
-
command_parts = [
|
31
|
-
exe_path,
|
32
|
-
"framework-check",
|
33
|
-
"--project-tfms",
|
34
|
-
*project_tfms,
|
35
|
-
"--package-tfms",
|
36
|
-
*package_tfms
|
37
|
-
]
|
38
|
-
command = Shellwords.join(command_parts)
|
39
|
-
|
40
|
-
fingerprint = [
|
41
|
-
exe_path,
|
42
|
-
"framework-check",
|
43
|
-
"--project-tfms",
|
44
|
-
"<project-tfms>",
|
45
|
-
"--package-tfms",
|
46
|
-
"<package-tfms>"
|
47
|
-
].join(" ")
|
48
|
-
|
49
|
-
puts "running NuGet updater:\n" + command
|
50
|
-
|
51
|
-
output = SharedHelpers.run_shell_command(command, allow_unsafe_shell_command: true, fingerprint: fingerprint)
|
52
|
-
puts output
|
53
|
-
|
54
|
-
# Exit code == 0 means that all project frameworks are compatible
|
55
|
-
true
|
56
|
-
rescue Dependabot::SharedHelpers::HelperSubprocessFailed
|
57
|
-
# Exit code != 0 means that not all project frameworks are compatible
|
58
|
-
false
|
59
|
-
end
|
60
|
-
|
61
|
-
sig do
|
62
|
-
params(
|
63
|
-
job_path: String,
|
64
|
-
repo_root: String,
|
65
|
-
workspace_path: String,
|
66
|
-
output_path: String
|
67
|
-
).returns([String, String])
|
68
|
-
end
|
69
|
-
def self.get_nuget_discover_tool_command(job_path:, repo_root:, workspace_path:, output_path:)
|
70
|
-
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
71
|
-
command_parts = [
|
72
|
-
exe_path,
|
73
|
-
"discover",
|
74
|
-
"--job-id",
|
75
|
-
job_id,
|
76
|
-
"--job-path",
|
77
|
-
job_path,
|
78
|
-
"--repo-root",
|
79
|
-
repo_root,
|
80
|
-
"--workspace",
|
81
|
-
workspace_path,
|
82
|
-
"--output",
|
83
|
-
output_path
|
84
|
-
].compact
|
85
|
-
|
86
|
-
command = Shellwords.join(command_parts)
|
87
|
-
|
88
|
-
fingerprint = [
|
89
|
-
exe_path,
|
90
|
-
"discover",
|
91
|
-
"--job-id",
|
92
|
-
"<job-id>",
|
93
|
-
"--job-path",
|
94
|
-
"<job-path>",
|
95
|
-
"--repo-root",
|
96
|
-
"<repo-root>",
|
97
|
-
"--workspace",
|
98
|
-
"<path-to-workspace>",
|
99
|
-
"--output",
|
100
|
-
"<path-to-output>"
|
101
|
-
].compact.join(" ")
|
102
|
-
|
103
|
-
[command, fingerprint]
|
104
|
-
end
|
105
|
-
|
106
|
-
sig do
|
107
|
-
params(
|
108
|
-
job_path: String,
|
109
|
-
repo_root: String,
|
110
|
-
workspace_path: String,
|
111
|
-
output_path: String,
|
112
|
-
credentials: T::Array[Dependabot::Credential]
|
113
|
-
).void
|
114
|
-
end
|
115
|
-
def self.run_nuget_discover_tool(job_path:, repo_root:, workspace_path:, output_path:, credentials:)
|
116
|
-
(command, fingerprint) = get_nuget_discover_tool_command(job_path: job_path,
|
117
|
-
repo_root: repo_root,
|
118
|
-
workspace_path: workspace_path,
|
119
|
-
output_path: output_path)
|
120
|
-
|
121
|
-
puts "running NuGet discovery:\n" + command
|
122
|
-
|
123
|
-
NuGetConfigCredentialHelpers.patch_nuget_config_for_action(credentials) do
|
124
|
-
output = SharedHelpers.run_shell_command(command, allow_unsafe_shell_command: true, fingerprint: fingerprint)
|
125
|
-
puts output
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
sig do
|
130
|
-
params(job_path: String, repo_root: String, discovery_file_path: String, dependency_file_path: String,
|
131
|
-
analysis_folder_path: String).returns([String, String])
|
132
|
-
end
|
133
|
-
def self.get_nuget_analyze_tool_command(job_path:, repo_root:, discovery_file_path:, dependency_file_path:,
|
134
|
-
analysis_folder_path:)
|
135
|
-
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
136
|
-
command_parts = [
|
137
|
-
exe_path,
|
138
|
-
"analyze",
|
139
|
-
"--job-id",
|
140
|
-
job_id,
|
141
|
-
"--job-path",
|
142
|
-
job_path,
|
143
|
-
"--repo-root",
|
144
|
-
repo_root,
|
145
|
-
"--discovery-file-path",
|
146
|
-
discovery_file_path,
|
147
|
-
"--dependency-file-path",
|
148
|
-
dependency_file_path,
|
149
|
-
"--analysis-folder-path",
|
150
|
-
analysis_folder_path
|
151
|
-
].compact
|
152
|
-
|
153
|
-
command = Shellwords.join(command_parts)
|
154
|
-
|
155
|
-
fingerprint = [
|
156
|
-
exe_path,
|
157
|
-
"analyze",
|
158
|
-
"--job-id",
|
159
|
-
"<job-id>",
|
160
|
-
"--job-path",
|
161
|
-
"<job-path>",
|
162
|
-
"--discovery-file-path",
|
163
|
-
"<discovery-file-path>",
|
164
|
-
"--dependency-file-path",
|
165
|
-
"<dependency-file-path>",
|
166
|
-
"--analysis-folder-path",
|
167
|
-
"<analysis_folder_path>"
|
168
|
-
].compact.join(" ")
|
169
|
-
|
170
|
-
[command, fingerprint]
|
171
|
-
end
|
172
|
-
|
173
|
-
sig do
|
174
|
-
params(
|
175
|
-
job_path: String, repo_root: String, discovery_file_path: String, dependency_file_path: String,
|
176
|
-
analysis_folder_path: String, credentials: T::Array[Dependabot::Credential]
|
177
|
-
).void
|
178
|
-
end
|
179
|
-
def self.run_nuget_analyze_tool(job_path:, repo_root:, discovery_file_path:, dependency_file_path:,
|
180
|
-
analysis_folder_path:, credentials:)
|
181
|
-
(command, fingerprint) = get_nuget_analyze_tool_command(job_path: job_path,
|
182
|
-
repo_root: repo_root,
|
183
|
-
discovery_file_path: discovery_file_path,
|
184
|
-
dependency_file_path: dependency_file_path,
|
185
|
-
analysis_folder_path: analysis_folder_path)
|
186
|
-
|
187
|
-
puts "running NuGet analyze:\n" + command
|
188
|
-
|
189
|
-
NuGetConfigCredentialHelpers.patch_nuget_config_for_action(credentials) do
|
190
|
-
output = SharedHelpers.run_shell_command(command, allow_unsafe_shell_command: true, fingerprint: fingerprint)
|
191
|
-
puts output
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# rubocop:disable Metrics/MethodLength
|
196
|
-
sig do
|
197
|
-
params(job_path: String, repo_root: String, proj_path: String, dependency: Dependency,
|
198
|
-
is_transitive: T::Boolean, result_output_path: String).returns([String, String])
|
199
|
-
end
|
200
|
-
def self.get_nuget_updater_tool_command(job_path:, repo_root:, proj_path:, dependency:, is_transitive:,
|
201
|
-
result_output_path:)
|
202
|
-
exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
|
203
|
-
command_parts = [
|
204
|
-
exe_path,
|
205
|
-
"update",
|
206
|
-
"--job-id",
|
207
|
-
job_id,
|
208
|
-
"--job-path",
|
209
|
-
job_path,
|
210
|
-
"--repo-root",
|
211
|
-
repo_root,
|
212
|
-
"--solution-or-project",
|
213
|
-
proj_path,
|
214
|
-
"--dependency",
|
215
|
-
dependency.name,
|
216
|
-
"--new-version",
|
217
|
-
dependency.version,
|
218
|
-
"--previous-version",
|
219
|
-
dependency.previous_version,
|
220
|
-
is_transitive ? "--transitive" : nil,
|
221
|
-
"--result-output-path",
|
222
|
-
result_output_path
|
223
|
-
].compact
|
224
|
-
|
225
|
-
command = Shellwords.join(command_parts)
|
226
|
-
|
227
|
-
fingerprint = [
|
228
|
-
exe_path,
|
229
|
-
"update",
|
230
|
-
"--job-id",
|
231
|
-
"<job-id>",
|
232
|
-
"--job-path",
|
233
|
-
"<job-path>",
|
234
|
-
"--repo-root",
|
235
|
-
"<repo-root>",
|
236
|
-
"--solution-or-project",
|
237
|
-
"<path-to-solution-or-project>",
|
238
|
-
"--dependency",
|
239
|
-
"<dependency-name>",
|
240
|
-
"--new-version",
|
241
|
-
"<new-version>",
|
242
|
-
"--previous-version",
|
243
|
-
"<previous-version>",
|
244
|
-
is_transitive ? "--transitive" : nil,
|
245
|
-
"--result-output-path",
|
246
|
-
"<result-output-path>"
|
247
|
-
].compact.join(" ")
|
248
|
-
|
249
|
-
[command, fingerprint]
|
250
|
-
end
|
251
|
-
# rubocop:enable Metrics/MethodLength
|
252
|
-
|
253
|
-
sig { returns(String) }
|
254
|
-
def self.update_result_file_path
|
255
|
-
File.join(Dir.tmpdir, "update-result.json")
|
256
|
-
end
|
257
|
-
|
258
|
-
sig do
|
259
|
-
params(
|
260
|
-
job_path: String,
|
261
|
-
repo_root: String,
|
262
|
-
proj_path: String,
|
263
|
-
dependency: Dependency,
|
264
|
-
is_transitive: T::Boolean,
|
265
|
-
credentials: T::Array[Dependabot::Credential]
|
266
|
-
).void
|
267
|
-
end
|
268
|
-
def self.run_nuget_updater_tool(job_path:, repo_root:, proj_path:, dependency:, is_transitive:, credentials:)
|
269
|
-
(command, fingerprint) = get_nuget_updater_tool_command(job_path: job_path, repo_root: repo_root,
|
270
|
-
proj_path: proj_path, dependency: dependency,
|
271
|
-
is_transitive: is_transitive,
|
272
|
-
result_output_path: update_result_file_path)
|
273
|
-
|
274
|
-
puts "running NuGet updater:\n" + command
|
275
|
-
|
276
|
-
NuGetConfigCredentialHelpers.patch_nuget_config_for_action(credentials) do
|
277
|
-
output = SharedHelpers.run_shell_command(command,
|
278
|
-
allow_unsafe_shell_command: true,
|
279
|
-
fingerprint: fingerprint)
|
280
|
-
puts output
|
281
|
-
|
282
|
-
result_contents = File.read(update_result_file_path)
|
283
|
-
Dependabot.logger.info("update result: #{result_contents}")
|
284
|
-
result_json = T.let(JSON.parse(result_contents), T::Hash[String, T.untyped])
|
285
|
-
ensure_no_errors(result_json)
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
sig { void }
|
290
|
-
def self.normalize_file_names
|
291
|
-
# environment variables are required and the following will generate an actionable error message if they're not
|
292
|
-
_dependabot_repo_contents_path = ENV.fetch("DEPENDABOT_REPO_CONTENTS_PATH")
|
293
|
-
|
294
|
-
# this environment variable is directly used
|
295
|
-
dependabot_home = ENV.fetch("DEPENDABOT_HOME")
|
296
|
-
|
297
|
-
command = [
|
298
|
-
"pwsh",
|
299
|
-
"#{dependabot_home}/dependabot-updater/bin/normalize-file-names.ps1"
|
300
|
-
].join(" ")
|
301
|
-
output = SharedHelpers.run_shell_command(command)
|
302
|
-
puts output
|
303
|
-
end
|
304
|
-
|
305
|
-
sig { void }
|
306
|
-
def self.install_dotnet_sdks
|
307
|
-
return unless Dependabot::Experiments.enabled?(:nuget_install_dotnet_sdks)
|
308
|
-
|
309
|
-
# environment variables are required and the following will generate an actionable error message if they're not
|
310
|
-
_dependabot_job_path = ENV.fetch("DEPENDABOT_JOB_PATH")
|
311
|
-
_dependabot_repo_contents_path = ENV.fetch("DEPENDABOT_REPO_CONTENTS_PATH")
|
312
|
-
_dotnet_install_script_path = ENV.fetch("DOTNET_INSTALL_SCRIPT_PATH")
|
313
|
-
_dotnet_install_dir = ENV.fetch("DOTNET_INSTALL_DIR")
|
314
|
-
|
315
|
-
# this environment variable is directly used
|
316
|
-
dependabot_home = ENV.fetch("DEPENDABOT_HOME")
|
317
|
-
|
318
|
-
command = [
|
319
|
-
"pwsh",
|
320
|
-
"#{dependabot_home}/dependabot-updater/bin/install-sdks.ps1"
|
321
|
-
].join(" ")
|
322
|
-
output = SharedHelpers.run_shell_command(command)
|
323
|
-
puts output
|
324
|
-
end
|
325
|
-
|
326
|
-
# rubocop:disable Metrics/AbcSize
|
327
|
-
sig { params(json: T::Hash[String, T.untyped]).void }
|
328
|
-
def self.ensure_no_errors(json)
|
329
|
-
error = T.let(json.fetch("Error", nil), T.nilable(T::Hash[String, T.untyped]))
|
330
|
-
return if error.nil?
|
331
|
-
|
332
|
-
error_type = T.let(error.fetch("error-type"), String)
|
333
|
-
error_details = T.let(error.fetch("error-details", {}), T::Hash[String, T.untyped])
|
334
|
-
|
335
|
-
case error_type
|
336
|
-
when "dependency_file_not_found"
|
337
|
-
file_path = T.let(error_details.fetch("file-path"), String)
|
338
|
-
message = T.let(error_details.fetch("message", nil), T.nilable(String))
|
339
|
-
raise DependencyFileNotFound.new(file_path, message)
|
340
|
-
when "dependency_file_not_parseable"
|
341
|
-
file_path = T.let(error_details.fetch("file-path"), String)
|
342
|
-
message = T.let(error_details.fetch("message", nil), T.nilable(String))
|
343
|
-
raise DependencyFileNotParseable.new(file_path, message)
|
344
|
-
when "dependency_not_found"
|
345
|
-
source = T.let(error_details.fetch("source"), String)
|
346
|
-
raise DependencyNotFound, source
|
347
|
-
when "illformed_requirement"
|
348
|
-
raise BadRequirementError, T.let(error_details.fetch("message"), String)
|
349
|
-
when "private_source_authentication_failure"
|
350
|
-
raise PrivateSourceAuthenticationFailure, T.let(error_details.fetch("source"), String)
|
351
|
-
when "private_source_bad_response"
|
352
|
-
raise PrivateSourceBadResponse, T.let(error_details.fetch("source"), String)
|
353
|
-
when "update_not_possible"
|
354
|
-
raise UpdateNotPossible, T.let(error_details.fetch("dependencies"), T::Array[String])
|
355
|
-
when "unknown_error"
|
356
|
-
raise DependabotError, error_details.to_json
|
357
|
-
else
|
358
|
-
raise "Unexpected error type from native tool: #{error_type}: #{error_details}"
|
359
|
-
end
|
360
|
-
end
|
361
|
-
# rubocop:enable Metrics/AbcSize
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "sorbet-runtime"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module Nuget
|
8
|
-
module NuGetConfigCredentialHelpers
|
9
|
-
extend T::Sig
|
10
|
-
|
11
|
-
sig { returns(String) }
|
12
|
-
def self.user_nuget_config_path
|
13
|
-
home_directory = Dir.home
|
14
|
-
File.join(home_directory, ".nuget", "NuGet", "NuGet.Config")
|
15
|
-
end
|
16
|
-
|
17
|
-
sig { returns(String) }
|
18
|
-
def self.temporary_nuget_config_path
|
19
|
-
user_nuget_config_path + "_ORIGINAL"
|
20
|
-
end
|
21
|
-
|
22
|
-
sig { params(credentials: T::Array[Dependabot::Credential]).void }
|
23
|
-
def self.add_credentials_to_nuget_config(credentials)
|
24
|
-
return unless File.exist?(user_nuget_config_path)
|
25
|
-
|
26
|
-
nuget_credentials = credentials.select { |cred| cred["type"] == "nuget_feed" }
|
27
|
-
return if nuget_credentials.empty?
|
28
|
-
|
29
|
-
File.rename(user_nuget_config_path, temporary_nuget_config_path)
|
30
|
-
|
31
|
-
package_sources = [" <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />"]
|
32
|
-
package_source_credentials = []
|
33
|
-
nuget_credentials.each_with_index do |c, i|
|
34
|
-
source_name = "nuget_source_#{i + 1}"
|
35
|
-
package_sources << " <add key=\"#{source_name}\" value=\"#{c['url']}\" />"
|
36
|
-
next unless c["token"]
|
37
|
-
|
38
|
-
package_source_credentials << " <#{source_name}>"
|
39
|
-
package_source_credentials << " <add key=\"Username\" value=\"user\" />"
|
40
|
-
package_source_credentials << " <add key=\"ClearTextPassword\" value=\"#{c['token']}\" />"
|
41
|
-
package_source_credentials << " </#{source_name}>"
|
42
|
-
end
|
43
|
-
|
44
|
-
nuget_config = <<~NUGET_XML
|
45
|
-
<?xml version="1.0" encoding="utf-8"?>
|
46
|
-
<configuration>
|
47
|
-
<packageSources>
|
48
|
-
#{package_sources.join("\n")}
|
49
|
-
</packageSources>
|
50
|
-
<packageSourceCredentials>
|
51
|
-
#{package_source_credentials.join("\n")}
|
52
|
-
</packageSourceCredentials>
|
53
|
-
</configuration>
|
54
|
-
NUGET_XML
|
55
|
-
File.write(user_nuget_config_path, nuget_config)
|
56
|
-
end
|
57
|
-
|
58
|
-
sig { void }
|
59
|
-
def self.restore_user_nuget_config
|
60
|
-
return unless File.exist?(temporary_nuget_config_path)
|
61
|
-
|
62
|
-
File.delete(user_nuget_config_path)
|
63
|
-
File.rename(temporary_nuget_config_path, user_nuget_config_path)
|
64
|
-
end
|
65
|
-
|
66
|
-
sig { params(credentials: T::Array[Dependabot::Credential], _block: T.proc.void).void }
|
67
|
-
def self.patch_nuget_config_for_action(credentials, &_block)
|
68
|
-
add_credentials_to_nuget_config(credentials)
|
69
|
-
begin
|
70
|
-
yield
|
71
|
-
rescue DependabotError
|
72
|
-
# forward these
|
73
|
-
raise
|
74
|
-
rescue StandardError => e
|
75
|
-
log_message =
|
76
|
-
<<~LOG_MESSAGE
|
77
|
-
Block argument of NuGetConfigCredentialHelpers::patch_nuget_config_for_action causes an exception #{e}:
|
78
|
-
#{e.message}
|
79
|
-
LOG_MESSAGE
|
80
|
-
Dependabot.logger.error(log_message)
|
81
|
-
puts log_message
|
82
|
-
ensure
|
83
|
-
restore_user_nuget_config
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "sorbet-runtime"
|
5
|
-
require "dependabot/nuget/version"
|
6
|
-
require "dependabot/ecosystem"
|
7
|
-
require "dependabot/nuget/requirement"
|
8
|
-
|
9
|
-
module Dependabot
|
10
|
-
module Nuget
|
11
|
-
ECOSYSTEM = "dotnet"
|
12
|
-
|
13
|
-
SUPPORTED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])
|
14
|
-
|
15
|
-
DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])
|
16
|
-
|
17
|
-
class NugetPackageManager < Dependabot::Ecosystem::VersionManager
|
18
|
-
extend T::Sig
|
19
|
-
|
20
|
-
NAME = "nuget"
|
21
|
-
|
22
|
-
SUPPORTED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])
|
23
|
-
|
24
|
-
DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])
|
25
|
-
|
26
|
-
sig do
|
27
|
-
params(
|
28
|
-
raw_version: T.nilable(String)
|
29
|
-
).void
|
30
|
-
end
|
31
|
-
def initialize(raw_version)
|
32
|
-
super(
|
33
|
-
name: NAME,
|
34
|
-
version: Version.new(raw_version),
|
35
|
-
deprecated_versions: DEPRECATED_VERSIONS,
|
36
|
-
supported_versions: SUPPORTED_VERSIONS
|
37
|
-
)
|
38
|
-
end
|
39
|
-
|
40
|
-
sig { override.returns(T::Boolean) }
|
41
|
-
def deprecated?
|
42
|
-
false
|
43
|
-
end
|
44
|
-
|
45
|
-
sig { override.returns(T::Boolean) }
|
46
|
-
def unsupported?
|
47
|
-
false
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|