dependabot-nuget 0.289.0 → 0.291.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/Directory.Packages.props +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +26 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +6 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +17 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +44 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +19 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +24 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +43 -18
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +13 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +40 -14
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +45 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +0 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +41 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +7 -31
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +340 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +0 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +55 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +785 -755
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +2 -2
- data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +1 -1
- data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
- data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
- data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
- data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
- data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
- data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
- data/lib/dependabot/nuget/file_fetcher.rb +3 -3
- data/lib/dependabot/nuget/file_parser.rb +92 -3
- data/lib/dependabot/nuget/file_updater.rb +13 -13
- data/lib/dependabot/nuget/language.rb +82 -0
- data/lib/dependabot/nuget/native_helpers.rb +37 -5
- data/lib/dependabot/nuget/package_manager.rb +51 -0
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
- data/lib/dependabot/nuget/update_checker.rb +116 -190
- metadata +20 -29
- data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
- data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
- data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
- data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -122
- data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -277
- data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
- data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -104
- data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
- data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -61
- data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
- data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -214
- data/lib/dependabot/nuget/nuget_client.rb +0 -223
- data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
- data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
- data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
- data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
- data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
- data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
- data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
- data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
- data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -1,43 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "sorbet-runtime"
|
5
|
-
|
6
|
-
module Dependabot
|
7
|
-
module Nuget
|
8
|
-
class NativePropertyDetails
|
9
|
-
extend T::Sig
|
10
|
-
|
11
|
-
sig { params(json: T::Hash[String, T.untyped]).returns(NativePropertyDetails) }
|
12
|
-
def self.from_json(json)
|
13
|
-
name = T.let(json.fetch("Name"), String)
|
14
|
-
value = T.let(json.fetch("Value"), String)
|
15
|
-
source_file_path = T.let(json.fetch("SourceFilePath"), String)
|
16
|
-
|
17
|
-
NativePropertyDetails.new(name: name,
|
18
|
-
value: value,
|
19
|
-
source_file_path: source_file_path)
|
20
|
-
end
|
21
|
-
|
22
|
-
sig do
|
23
|
-
params(name: String,
|
24
|
-
value: String,
|
25
|
-
source_file_path: String).void
|
26
|
-
end
|
27
|
-
def initialize(name:, value:, source_file_path:)
|
28
|
-
@name = name
|
29
|
-
@value = value
|
30
|
-
@source_file_path = source_file_path
|
31
|
-
end
|
32
|
-
|
33
|
-
sig { returns(String) }
|
34
|
-
attr_reader :name
|
35
|
-
|
36
|
-
sig { returns(String) }
|
37
|
-
attr_reader :value
|
38
|
-
|
39
|
-
sig { returns(String) }
|
40
|
-
attr_reader :source_file_path
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "dependabot/nuget/native_discovery/native_dependency_file_discovery"
|
5
|
-
require "dependabot/nuget/native_discovery/native_project_discovery"
|
6
|
-
require "dependabot/nuget/native_helpers"
|
7
|
-
require "sorbet-runtime"
|
8
|
-
|
9
|
-
module Dependabot
|
10
|
-
module Nuget
|
11
|
-
class NativeWorkspaceDiscovery
|
12
|
-
extend T::Sig
|
13
|
-
|
14
|
-
sig { params(json: T::Hash[String, T.untyped]).returns(NativeWorkspaceDiscovery) }
|
15
|
-
def self.from_json(json)
|
16
|
-
Dependabot::Nuget::NativeHelpers.ensure_no_errors(json)
|
17
|
-
|
18
|
-
path = T.let(json.fetch("Path"), String)
|
19
|
-
path = "/" + path unless path.start_with?("/")
|
20
|
-
projects = T.let(json.fetch("Projects"), T::Array[T::Hash[String, T.untyped]]).filter_map do |project|
|
21
|
-
NativeProjectDiscovery.from_json(project, path)
|
22
|
-
end
|
23
|
-
global_json = NativeDependencyFileDiscovery
|
24
|
-
.from_json(T.let(json.fetch("GlobalJson"), T.nilable(T::Hash[String, T.untyped])), path)
|
25
|
-
dotnet_tools_json = NativeDependencyFileDiscovery
|
26
|
-
.from_json(T.let(json.fetch("DotNetToolsJson"),
|
27
|
-
T.nilable(T::Hash[String, T.untyped])), path)
|
28
|
-
|
29
|
-
NativeWorkspaceDiscovery.new(path: path,
|
30
|
-
projects: projects,
|
31
|
-
global_json: global_json,
|
32
|
-
dotnet_tools_json: dotnet_tools_json)
|
33
|
-
end
|
34
|
-
|
35
|
-
sig do
|
36
|
-
params(path: String,
|
37
|
-
projects: T::Array[NativeProjectDiscovery],
|
38
|
-
global_json: T.nilable(NativeDependencyFileDiscovery),
|
39
|
-
dotnet_tools_json: T.nilable(NativeDependencyFileDiscovery)).void
|
40
|
-
end
|
41
|
-
def initialize(path:, projects:, global_json:, dotnet_tools_json:)
|
42
|
-
@path = path
|
43
|
-
@projects = projects
|
44
|
-
@global_json = global_json
|
45
|
-
@dotnet_tools_json = dotnet_tools_json
|
46
|
-
end
|
47
|
-
|
48
|
-
sig { returns(String) }
|
49
|
-
attr_reader :path
|
50
|
-
|
51
|
-
sig { returns(T::Array[NativeProjectDiscovery]) }
|
52
|
-
attr_reader :projects
|
53
|
-
|
54
|
-
sig { returns(T.nilable(NativeDependencyFileDiscovery)) }
|
55
|
-
attr_reader :global_json
|
56
|
-
|
57
|
-
sig { returns(T.nilable(NativeDependencyFileDiscovery)) }
|
58
|
-
attr_reader :dotnet_tools_json
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
#######################################################################
|
5
|
-
# For more details on Dotnet version constraints, see: #
|
6
|
-
# https://docs.microsoft.com/en-us/nuget/reference/package-versioning #
|
7
|
-
#######################################################################
|
8
|
-
|
9
|
-
require "sorbet-runtime"
|
10
|
-
|
11
|
-
require "dependabot/update_checkers/base"
|
12
|
-
require "dependabot/nuget/native_discovery/native_dependency_details"
|
13
|
-
require "dependabot/nuget/version"
|
14
|
-
|
15
|
-
module Dependabot
|
16
|
-
module Nuget
|
17
|
-
class NativeUpdateChecker < Dependabot::UpdateCheckers::Base
|
18
|
-
class NativeRequirementsUpdater
|
19
|
-
extend T::Sig
|
20
|
-
|
21
|
-
sig do
|
22
|
-
params(
|
23
|
-
requirements: T::Array[T::Hash[Symbol, T.untyped]],
|
24
|
-
dependency_details: T.nilable(Dependabot::Nuget::NativeDependencyDetails)
|
25
|
-
)
|
26
|
-
.void
|
27
|
-
end
|
28
|
-
def initialize(requirements:, dependency_details:)
|
29
|
-
@requirements = requirements
|
30
|
-
@dependency_details = dependency_details
|
31
|
-
end
|
32
|
-
|
33
|
-
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
34
|
-
def updated_requirements
|
35
|
-
return requirements unless clean_version
|
36
|
-
|
37
|
-
# NOTE: Order is important here. The FileUpdater needs the updated
|
38
|
-
# requirement at index `i` to correspond to the previous requirement
|
39
|
-
# at the same index.
|
40
|
-
requirements.map do |req|
|
41
|
-
next req if req.fetch(:requirement).nil?
|
42
|
-
next req if req.fetch(:requirement).include?(",")
|
43
|
-
|
44
|
-
new_req =
|
45
|
-
if req.fetch(:requirement).include?("*")
|
46
|
-
update_wildcard_requirement(req.fetch(:requirement))
|
47
|
-
else
|
48
|
-
# Since range requirements are excluded by the line above we can
|
49
|
-
# replace anything that looks like a version with the new
|
50
|
-
# version
|
51
|
-
req[:requirement].sub(
|
52
|
-
/#{Nuget::Version::VERSION_PATTERN}/o,
|
53
|
-
clean_version.to_s
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
next req if new_req == req.fetch(:requirement)
|
58
|
-
|
59
|
-
new_source = req[:source]&.dup
|
60
|
-
unless @dependency_details.nil?
|
61
|
-
new_source = {
|
62
|
-
type: "nuget_repo",
|
63
|
-
source_url: @dependency_details.info_url
|
64
|
-
}
|
65
|
-
end
|
66
|
-
|
67
|
-
req.merge({ requirement: new_req, source: new_source })
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
74
|
-
attr_reader :requirements
|
75
|
-
|
76
|
-
sig { returns(T.class_of(Dependabot::Nuget::Version)) }
|
77
|
-
def version_class
|
78
|
-
Dependabot::Nuget::Version
|
79
|
-
end
|
80
|
-
|
81
|
-
sig { returns(T.nilable(Dependabot::Nuget::Version)) }
|
82
|
-
def clean_version
|
83
|
-
return unless @dependency_details&.version
|
84
|
-
|
85
|
-
version_class.new(@dependency_details.version)
|
86
|
-
end
|
87
|
-
|
88
|
-
sig { params(req_string: String).returns(String) }
|
89
|
-
def update_wildcard_requirement(req_string)
|
90
|
-
return req_string if req_string == "*-*"
|
91
|
-
|
92
|
-
return req_string if req_string == "*"
|
93
|
-
|
94
|
-
precision = T.must(req_string.split("*").first).split(/\.|\-/).count
|
95
|
-
wildcard_section = req_string.partition(/(?=[.\-]\*)/).last
|
96
|
-
|
97
|
-
version_parts = T.must(clean_version).segments.first(precision)
|
98
|
-
version = version_parts.join(".")
|
99
|
-
|
100
|
-
version + wildcard_section
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,214 +0,0 @@
|
|
1
|
-
# typed: strong
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "dependabot/nuget/analysis/analysis_json_reader"
|
5
|
-
require "dependabot/nuget/native_discovery/native_discovery_json_reader"
|
6
|
-
require "dependabot/update_checkers"
|
7
|
-
require "dependabot/update_checkers/base"
|
8
|
-
require "sorbet-runtime"
|
9
|
-
|
10
|
-
module Dependabot
|
11
|
-
module Nuget
|
12
|
-
class NativeUpdateChecker < Dependabot::UpdateCheckers::Base
|
13
|
-
extend T::Sig
|
14
|
-
|
15
|
-
require_relative "native_requirements_updater"
|
16
|
-
|
17
|
-
sig { override.returns(T.nilable(String)) }
|
18
|
-
def latest_version
|
19
|
-
# No need to find latest version for transitive dependencies unless they have a vulnerability.
|
20
|
-
return dependency.version if !dependency.top_level? && !vulnerable?
|
21
|
-
|
22
|
-
# if no update sources have the requisite package, then we can only assume that the current version is correct
|
23
|
-
@latest_version = T.let(
|
24
|
-
update_analysis.dependency_analysis.updated_version,
|
25
|
-
T.nilable(String)
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
|
-
sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
|
30
|
-
def latest_resolvable_version
|
31
|
-
# We always want a full unlock since any package update could update peer dependencies as well.
|
32
|
-
# To force a full unlock instead of an own unlock, we return nil.
|
33
|
-
nil
|
34
|
-
end
|
35
|
-
|
36
|
-
sig { override.returns(Dependabot::Nuget::Version) }
|
37
|
-
def lowest_security_fix_version
|
38
|
-
update_analysis.dependency_analysis.numeric_updated_version
|
39
|
-
end
|
40
|
-
|
41
|
-
sig { override.returns(T.nilable(Dependabot::Nuget::Version)) }
|
42
|
-
def lowest_resolvable_security_fix_version
|
43
|
-
return nil if version_comes_from_multi_dependency_property?
|
44
|
-
|
45
|
-
update_analysis.dependency_analysis.numeric_updated_version
|
46
|
-
end
|
47
|
-
|
48
|
-
sig { override.returns(NilClass) }
|
49
|
-
def latest_resolvable_version_with_no_unlock
|
50
|
-
# Irrelevant, since Nuget has a single dependency file
|
51
|
-
nil
|
52
|
-
end
|
53
|
-
|
54
|
-
sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
55
|
-
def updated_requirements
|
56
|
-
dep_details = updated_dependency_details.find { |d| d.name.casecmp?(dependency.name) }
|
57
|
-
NativeRequirementsUpdater.new(
|
58
|
-
requirements: dependency.requirements,
|
59
|
-
dependency_details: dep_details
|
60
|
-
).updated_requirements
|
61
|
-
end
|
62
|
-
|
63
|
-
sig { returns(T::Boolean) }
|
64
|
-
def up_to_date?
|
65
|
-
!update_analysis.dependency_analysis.can_update
|
66
|
-
end
|
67
|
-
|
68
|
-
sig { returns(T::Boolean) }
|
69
|
-
def requirements_unlocked_or_can_be?
|
70
|
-
update_analysis.dependency_analysis.can_update
|
71
|
-
end
|
72
|
-
|
73
|
-
sig { returns(T::Boolean) }
|
74
|
-
def public_latest_version_resolvable_with_full_unlock?
|
75
|
-
latest_version_resolvable_with_full_unlock?
|
76
|
-
end
|
77
|
-
|
78
|
-
sig { returns(T::Array[Dependabot::Dependency]) }
|
79
|
-
def public_updated_dependencies_after_full_unlock
|
80
|
-
updated_dependencies_after_full_unlock
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
sig { returns(AnalysisJsonReader) }
|
86
|
-
def update_analysis
|
87
|
-
@update_analysis ||= T.let(request_analysis, T.nilable(AnalysisJsonReader))
|
88
|
-
end
|
89
|
-
|
90
|
-
sig { returns(String) }
|
91
|
-
def dependency_file_path
|
92
|
-
d = File.join(Dir.tmpdir, "dependency")
|
93
|
-
FileUtils.mkdir_p(d)
|
94
|
-
File.join(d, "#{dependency.name}.json")
|
95
|
-
end
|
96
|
-
|
97
|
-
sig { returns(T::Array[String]) }
|
98
|
-
def dependency_file_paths
|
99
|
-
dependency_files.map do |file|
|
100
|
-
NativeDiscoveryJsonReader.dependency_file_path(
|
101
|
-
repo_contents_path: T.must(repo_contents_path),
|
102
|
-
dependency_file: file
|
103
|
-
)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
sig { returns(AnalysisJsonReader) }
|
108
|
-
def request_analysis
|
109
|
-
discovery_file_path = NativeDiscoveryJsonReader.get_discovery_json_path_for_dependency_file_paths(
|
110
|
-
dependency_file_paths
|
111
|
-
)
|
112
|
-
analysis_folder_path = AnalysisJsonReader.temp_directory
|
113
|
-
|
114
|
-
write_dependency_info
|
115
|
-
|
116
|
-
NativeHelpers.run_nuget_analyze_tool(repo_root: T.must(repo_contents_path),
|
117
|
-
discovery_file_path: discovery_file_path,
|
118
|
-
dependency_file_path: dependency_file_path,
|
119
|
-
analysis_folder_path: analysis_folder_path,
|
120
|
-
credentials: credentials)
|
121
|
-
|
122
|
-
analysis_json = AnalysisJsonReader.analysis_json(dependency_name: dependency.name)
|
123
|
-
|
124
|
-
AnalysisJsonReader.new(analysis_json: T.must(analysis_json))
|
125
|
-
end
|
126
|
-
|
127
|
-
sig { void }
|
128
|
-
def write_dependency_info
|
129
|
-
dependency_info = {
|
130
|
-
Name: dependency.name,
|
131
|
-
Version: dependency.version.to_s,
|
132
|
-
IsVulnerable: vulnerable?,
|
133
|
-
IgnoredVersions: ignored_versions,
|
134
|
-
Vulnerabilities: security_advisories.map do |vulnerability|
|
135
|
-
{
|
136
|
-
DependencyName: vulnerability.dependency_name,
|
137
|
-
PackageManager: vulnerability.package_manager,
|
138
|
-
VulnerableVersions: vulnerability.vulnerable_versions.map(&:to_s),
|
139
|
-
SafeVersions: vulnerability.safe_versions.map(&:to_s)
|
140
|
-
}
|
141
|
-
end
|
142
|
-
}.to_json
|
143
|
-
dependency_directory = File.dirname(dependency_file_path)
|
144
|
-
|
145
|
-
begin
|
146
|
-
Dir.mkdir(dependency_directory)
|
147
|
-
rescue StandardError
|
148
|
-
nil?
|
149
|
-
end
|
150
|
-
|
151
|
-
Dependabot.logger.info("Writing dependency info: #{dependency_info}")
|
152
|
-
File.write(dependency_file_path, dependency_info)
|
153
|
-
end
|
154
|
-
|
155
|
-
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
|
156
|
-
def discovered_dependencies
|
157
|
-
NativeDiscoveryJsonReader.load_discovery_for_dependency_file_paths(dependency_file_paths).dependency_set
|
158
|
-
end
|
159
|
-
|
160
|
-
sig { override.returns(T::Boolean) }
|
161
|
-
def latest_version_resolvable_with_full_unlock?
|
162
|
-
# We always want a full unlock since any package update could update peer dependencies as well.
|
163
|
-
true
|
164
|
-
end
|
165
|
-
|
166
|
-
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
167
|
-
def updated_dependencies_after_full_unlock
|
168
|
-
dependencies = discovered_dependencies.dependencies
|
169
|
-
updated_dependency_details.filter_map do |dependency_details|
|
170
|
-
dep = dependencies.find { |d| d.name.casecmp(dependency_details.name)&.zero? }
|
171
|
-
next unless dep
|
172
|
-
|
173
|
-
metadata = {}
|
174
|
-
# For peer dependencies, instruct updater to not directly update this dependency
|
175
|
-
metadata = { information_only: true } unless dependency.name.casecmp(dependency_details.name)&.zero?
|
176
|
-
|
177
|
-
# rebuild the new requirements with the updated dependency details
|
178
|
-
updated_reqs = dep.requirements.map do |r|
|
179
|
-
r = r.clone
|
180
|
-
r[:requirement] = dependency_details.version
|
181
|
-
r[:source] = {
|
182
|
-
type: "nuget_repo",
|
183
|
-
source_url: dependency_details.info_url
|
184
|
-
}
|
185
|
-
r
|
186
|
-
end
|
187
|
-
|
188
|
-
Dependency.new(
|
189
|
-
name: dep.name,
|
190
|
-
version: dependency_details.version,
|
191
|
-
requirements: updated_reqs,
|
192
|
-
previous_version: dep.version,
|
193
|
-
previous_requirements: dep.requirements,
|
194
|
-
package_manager: dep.package_manager,
|
195
|
-
metadata: metadata
|
196
|
-
)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
sig { returns(T::Array[Dependabot::Nuget::NativeDependencyDetails]) }
|
201
|
-
def updated_dependency_details
|
202
|
-
@updated_dependency_details ||= T.let(update_analysis.dependency_analysis.updated_dependencies,
|
203
|
-
T.nilable(T::Array[Dependabot::Nuget::NativeDependencyDetails]))
|
204
|
-
end
|
205
|
-
|
206
|
-
sig { returns(T::Boolean) }
|
207
|
-
def version_comes_from_multi_dependency_property?
|
208
|
-
update_analysis.dependency_analysis.version_comes_from_multi_dependency_property
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
Dependabot::UpdateCheckers.register("nuget", Dependabot::Nuget::UpdateChecker)
|
@@ -1,223 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "dependabot/nuget/cache_manager"
|
5
|
-
require "dependabot/nuget/http_response_helpers"
|
6
|
-
require "dependabot/nuget/update_checker/repository_finder"
|
7
|
-
require "sorbet-runtime"
|
8
|
-
|
9
|
-
module Dependabot
|
10
|
-
module Nuget
|
11
|
-
class NugetClient
|
12
|
-
extend T::Sig
|
13
|
-
|
14
|
-
sig do
|
15
|
-
params(dependency_name: String, repository_details: T::Hash[Symbol, String])
|
16
|
-
.returns(T.nilable(T::Set[String]))
|
17
|
-
end
|
18
|
-
def self.get_package_versions(dependency_name, repository_details)
|
19
|
-
repository_type = repository_details.fetch(:repository_type)
|
20
|
-
if repository_type == "v3"
|
21
|
-
get_package_versions_v3(dependency_name, repository_details)
|
22
|
-
elsif repository_type == "v2"
|
23
|
-
get_package_versions_v2(dependency_name, repository_details)
|
24
|
-
elsif repository_type == "local"
|
25
|
-
get_package_versions_local(dependency_name, repository_details)
|
26
|
-
else
|
27
|
-
raise "Unknown repository type: #{repository_type}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
sig do
|
32
|
-
params(dependency_name: String, repository_details: T::Hash[Symbol, String])
|
33
|
-
.returns(T.nilable(T::Set[String]))
|
34
|
-
end
|
35
|
-
private_class_method def self.get_package_versions_local(dependency_name, repository_details)
|
36
|
-
url = repository_details.fetch(:base_url)
|
37
|
-
raise "Local repo #{url} doesn't exist or isn't a directory" unless File.exist?(url) && File.directory?(url)
|
38
|
-
|
39
|
-
package_dir = File.join(url, dependency_name)
|
40
|
-
|
41
|
-
versions = Set.new
|
42
|
-
return versions unless File.exist?(package_dir) && File.directory?(package_dir)
|
43
|
-
|
44
|
-
Dir.each_child(package_dir) do |child|
|
45
|
-
versions.add(child) if File.directory?(File.join(package_dir, child))
|
46
|
-
end
|
47
|
-
|
48
|
-
versions
|
49
|
-
end
|
50
|
-
|
51
|
-
sig do
|
52
|
-
params(dependency_name: String, repository_details: T::Hash[Symbol, String])
|
53
|
-
.returns(T.nilable(T::Set[String]))
|
54
|
-
end
|
55
|
-
private_class_method def self.get_package_versions_v3(dependency_name, repository_details)
|
56
|
-
# Use the registration URL if possible because it is fast and correct
|
57
|
-
if repository_details[:registration_url]
|
58
|
-
get_versions_from_registration_v3(repository_details)
|
59
|
-
# use the search API if not because it is slow but correct
|
60
|
-
elsif repository_details[:search_url]
|
61
|
-
get_versions_from_search_url_v3(repository_details, dependency_name)
|
62
|
-
# Otherwise, use the versions URL (fast but wrong because it includes unlisted versions)
|
63
|
-
elsif repository_details[:versions_url]
|
64
|
-
get_versions_from_versions_url_v3(repository_details)
|
65
|
-
else
|
66
|
-
raise "No version sources were available for #{dependency_name} in #{repository_details}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
sig do
|
71
|
-
params(dependency_name: String, repository_details: T::Hash[Symbol, String])
|
72
|
-
.returns(T.nilable(T::Set[String]))
|
73
|
-
end
|
74
|
-
private_class_method def self.get_package_versions_v2(dependency_name, repository_details)
|
75
|
-
doc = execute_xml_nuget_request(repository_details.fetch(:versions_url), repository_details)
|
76
|
-
return unless doc
|
77
|
-
|
78
|
-
# v2 APIs can differ, but all tested have this title value set to the name of the package
|
79
|
-
title_nodes = doc.xpath("/feed/entry/title")
|
80
|
-
matching_versions = Set.new
|
81
|
-
title_nodes.each do |title_node|
|
82
|
-
return nil unless title_node.text
|
83
|
-
|
84
|
-
next unless title_node.text.casecmp?(dependency_name)
|
85
|
-
|
86
|
-
version_node = title_node.parent.xpath("properties/Version")
|
87
|
-
matching_versions << version_node.text if version_node && version_node.text
|
88
|
-
end
|
89
|
-
|
90
|
-
matching_versions
|
91
|
-
end
|
92
|
-
|
93
|
-
sig { params(repository_details: T::Hash[Symbol, String]).returns(T.nilable(T::Set[String])) }
|
94
|
-
private_class_method def self.get_versions_from_versions_url_v3(repository_details)
|
95
|
-
body = execute_json_nuget_request(repository_details.fetch(:versions_url), repository_details)
|
96
|
-
ver_array = T.let(body&.fetch("versions"), T.nilable(T::Array[String]))
|
97
|
-
ver_array&.to_set
|
98
|
-
end
|
99
|
-
|
100
|
-
sig { params(repository_details: T::Hash[Symbol, String]).returns(T.nilable(T::Set[String])) }
|
101
|
-
private_class_method def self.get_versions_from_registration_v3(repository_details)
|
102
|
-
url = repository_details.fetch(:registration_url)
|
103
|
-
body = execute_json_nuget_request(url, repository_details)
|
104
|
-
|
105
|
-
return unless body
|
106
|
-
|
107
|
-
pages = body.fetch("items")
|
108
|
-
versions = T.let(Set.new, T::Set[String])
|
109
|
-
pages.each do |page|
|
110
|
-
items = page["items"]
|
111
|
-
if items
|
112
|
-
# inlined entries
|
113
|
-
get_versions_from_inline_page(items, versions)
|
114
|
-
else
|
115
|
-
# paged entries
|
116
|
-
page_url = page["@id"]
|
117
|
-
page_body = execute_json_nuget_request(page_url, repository_details)
|
118
|
-
next unless page_body
|
119
|
-
|
120
|
-
items = page_body.fetch("items")
|
121
|
-
items.each do |item|
|
122
|
-
catalog_entry = item.fetch("catalogEntry")
|
123
|
-
versions << catalog_entry.fetch("version") if catalog_entry["listed"] == true
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
versions
|
129
|
-
end
|
130
|
-
|
131
|
-
sig { params(items: T::Array[T::Hash[String, T.untyped]], versions: T::Set[String]).void }
|
132
|
-
private_class_method def self.get_versions_from_inline_page(items, versions)
|
133
|
-
items.each do |item|
|
134
|
-
catalog_entry = item["catalogEntry"]
|
135
|
-
|
136
|
-
# a package is considered listed if the `listed` property is either `true` or missing
|
137
|
-
listed_property = catalog_entry["listed"]
|
138
|
-
is_listed = listed_property.nil? || listed_property == true
|
139
|
-
if is_listed
|
140
|
-
vers = catalog_entry["version"]
|
141
|
-
versions << vers
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
sig do
|
147
|
-
params(repository_details: T::Hash[Symbol, String], dependency_name: String)
|
148
|
-
.returns(T.nilable(T::Set[String]))
|
149
|
-
end
|
150
|
-
private_class_method def self.get_versions_from_search_url_v3(repository_details, dependency_name)
|
151
|
-
search_url = repository_details.fetch(:search_url)
|
152
|
-
body = execute_json_nuget_request(search_url, repository_details)
|
153
|
-
|
154
|
-
body&.fetch("data")
|
155
|
-
&.find { |d| d.fetch("id").casecmp(dependency_name.downcase).zero? }
|
156
|
-
&.fetch("versions")
|
157
|
-
&.map { |d| d.fetch("version") }
|
158
|
-
&.to_set
|
159
|
-
end
|
160
|
-
|
161
|
-
sig do
|
162
|
-
params(url: String, repository_details: T::Hash[Symbol, T.untyped]).returns(T.nilable(Nokogiri::XML::Document))
|
163
|
-
end
|
164
|
-
private_class_method def self.execute_xml_nuget_request(url, repository_details)
|
165
|
-
response = execute_nuget_request_internal(
|
166
|
-
url: url,
|
167
|
-
auth_header: repository_details.fetch(:auth_header),
|
168
|
-
repository_url: repository_details.fetch(:repository_url)
|
169
|
-
)
|
170
|
-
return unless response.status == 200
|
171
|
-
|
172
|
-
doc = Nokogiri::XML(response.body)
|
173
|
-
doc.remove_namespaces!
|
174
|
-
doc
|
175
|
-
end
|
176
|
-
|
177
|
-
sig do
|
178
|
-
params(url: String,
|
179
|
-
repository_details: T::Hash[Symbol, T.untyped])
|
180
|
-
.returns(T.nilable(T::Hash[T.untyped, T.untyped]))
|
181
|
-
end
|
182
|
-
private_class_method def self.execute_json_nuget_request(url, repository_details)
|
183
|
-
response = execute_nuget_request_internal(
|
184
|
-
url: url,
|
185
|
-
auth_header: repository_details.fetch(:auth_header),
|
186
|
-
repository_url: repository_details.fetch(:repository_url)
|
187
|
-
)
|
188
|
-
return unless response.status == 200
|
189
|
-
|
190
|
-
body = HttpResponseHelpers.remove_wrapping_zero_width_chars(response.body)
|
191
|
-
JSON.parse(body)
|
192
|
-
end
|
193
|
-
|
194
|
-
sig do
|
195
|
-
params(url: String, auth_header: T::Hash[Symbol, T.untyped], repository_url: String).returns(Excon::Response)
|
196
|
-
end
|
197
|
-
private_class_method def self.execute_nuget_request_internal(url:, auth_header:, repository_url:)
|
198
|
-
cache = CacheManager.cache("dependency_url_search_cache")
|
199
|
-
if cache[url].nil?
|
200
|
-
response = Dependabot::RegistryClient.get(
|
201
|
-
url: url,
|
202
|
-
headers: auth_header
|
203
|
-
)
|
204
|
-
|
205
|
-
if [401, 402, 403].include?(response.status)
|
206
|
-
raise Dependabot::PrivateSourceAuthenticationFailure, repository_url
|
207
|
-
end
|
208
|
-
|
209
|
-
cache[url] = response if !CacheManager.caching_disabled? && response.status == 200
|
210
|
-
else
|
211
|
-
response = cache[url]
|
212
|
-
end
|
213
|
-
|
214
|
-
response
|
215
|
-
rescue Excon::Error::Timeout, Excon::Error::Socket
|
216
|
-
repo_url = repository_url
|
217
|
-
raise if repo_url == Dependabot::Nuget::RepositoryFinder::DEFAULT_REPOSITORY_URL
|
218
|
-
|
219
|
-
raise PrivateSourceTimedOut, repo_url
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|