dependabot-nuget 0.288.0 → 0.290.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +19 -17
  3. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +29 -2
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +25 -4
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +33 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +25 -10
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +60 -66
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +11 -3
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +1 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +54 -11
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +1 -2
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +67 -58
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +15 -44
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +2 -10
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +38 -33
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +25 -23
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +18 -17
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +17 -9
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +87 -5
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -5
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +16 -0
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +6 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +143 -36
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +184 -48
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -5
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +32 -10
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +402 -102
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +342 -2
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -14
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
  74. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +95 -0
  75. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -7
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +558 -711
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +47 -2
  80. data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +4 -2
  81. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
  82. data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
  83. data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
  84. data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
  85. data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
  86. data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
  87. data/lib/dependabot/nuget/file_fetcher.rb +11 -393
  88. data/lib/dependabot/nuget/file_parser.rb +23 -61
  89. data/lib/dependabot/nuget/file_updater.rb +28 -23
  90. data/lib/dependabot/nuget/native_helpers.rb +14 -5
  91. data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
  92. data/lib/dependabot/nuget/update_checker.rb +116 -190
  93. metadata +20 -32
  94. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
  95. data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
  96. data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
  97. data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
  98. data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
  99. data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
  100. data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -129
  101. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -171
  102. data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
  103. data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -82
  104. data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
  105. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -68
  106. data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
  107. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -201
  108. data/lib/dependabot/nuget/nuget_client.rb +0 -223
  109. data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
  110. data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
  111. data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
  112. data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
  113. data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
  114. data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
  115. data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
  116. data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
  117. data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
@@ -81,6 +81,8 @@ module Dependabot
81
81
  fingerprint = [
82
82
  exe_path,
83
83
  "discover",
84
+ "--job-path",
85
+ "<job-path>",
84
86
  "--repo-root",
85
87
  "<repo-root>",
86
88
  "--workspace",
@@ -116,15 +118,17 @@ module Dependabot
116
118
  end
117
119
 
118
120
  sig do
119
- params(repo_root: String, discovery_file_path: String, dependency_file_path: String,
121
+ params(job_path: String, repo_root: String, discovery_file_path: String, dependency_file_path: String,
120
122
  analysis_folder_path: String).returns([String, String])
121
123
  end
122
- def self.get_nuget_analyze_tool_command(repo_root:, discovery_file_path:, dependency_file_path:,
124
+ def self.get_nuget_analyze_tool_command(job_path:, repo_root:, discovery_file_path:, dependency_file_path:,
123
125
  analysis_folder_path:)
124
126
  exe_path = File.join(native_helpers_root, "NuGetUpdater", "NuGetUpdater.Cli")
125
127
  command_parts = [
126
128
  exe_path,
127
129
  "analyze",
130
+ "--job-path",
131
+ job_path,
128
132
  "--repo-root",
129
133
  repo_root,
130
134
  "--discovery-file-path",
@@ -140,6 +144,8 @@ module Dependabot
140
144
  fingerprint = [
141
145
  exe_path,
142
146
  "analyze",
147
+ "--job-path",
148
+ "<job-path>",
143
149
  "--discovery-file-path",
144
150
  "<discovery-file-path>",
145
151
  "--dependency-file-path",
@@ -153,13 +159,14 @@ module Dependabot
153
159
 
154
160
  sig do
155
161
  params(
156
- repo_root: String, discovery_file_path: String, dependency_file_path: String,
162
+ job_path: String, repo_root: String, discovery_file_path: String, dependency_file_path: String,
157
163
  analysis_folder_path: String, credentials: T::Array[Dependabot::Credential]
158
164
  ).void
159
165
  end
160
- def self.run_nuget_analyze_tool(repo_root:, discovery_file_path:, dependency_file_path:,
166
+ def self.run_nuget_analyze_tool(job_path:, repo_root:, discovery_file_path:, dependency_file_path:,
161
167
  analysis_folder_path:, credentials:)
162
- (command, fingerprint) = get_nuget_analyze_tool_command(repo_root: repo_root,
168
+ (command, fingerprint) = get_nuget_analyze_tool_command(job_path: job_path,
169
+ repo_root: repo_root,
163
170
  discovery_file_path: discovery_file_path,
164
171
  dependency_file_path: dependency_file_path,
165
172
  analysis_folder_path: analysis_folder_path)
@@ -205,6 +212,8 @@ module Dependabot
205
212
  fingerprint = [
206
213
  exe_path,
207
214
  "update",
215
+ "--job-path",
216
+ "<job-path>",
208
217
  "--repo-root",
209
218
  "<repo-root>",
210
219
  "--solution-or-project",
@@ -9,6 +9,7 @@
9
9
  require "sorbet-runtime"
10
10
 
11
11
  require "dependabot/update_checkers/base"
12
+ require "dependabot/nuget/discovery/dependency_details"
12
13
  require "dependabot/nuget/version"
13
14
 
14
15
  module Dependabot
@@ -20,22 +21,18 @@ module Dependabot
20
21
  sig do
21
22
  params(
22
23
  requirements: T::Array[T::Hash[Symbol, T.untyped]],
23
- latest_version: T.nilable(T.any(String, Dependabot::Nuget::Version)),
24
- source_details: T.nilable(T::Hash[Symbol, T.untyped])
24
+ dependency_details: T.nilable(Dependabot::Nuget::DependencyDetails)
25
25
  )
26
26
  .void
27
27
  end
28
- def initialize(requirements:, latest_version:, source_details:)
28
+ def initialize(requirements:, dependency_details:)
29
29
  @requirements = requirements
30
- @source_details = source_details
31
- return unless latest_version
32
-
33
- @latest_version = T.let(version_class.new(latest_version), Dependabot::Nuget::Version)
30
+ @dependency_details = dependency_details
34
31
  end
35
32
 
36
33
  sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
37
34
  def updated_requirements
38
- return requirements unless latest_version
35
+ return requirements unless clean_version
39
36
 
40
37
  # NOTE: Order is important here. The FileUpdater needs the updated
41
38
  # requirement at index `i` to correspond to the previous requirement
@@ -53,13 +50,21 @@ module Dependabot
53
50
  # version
54
51
  req[:requirement].sub(
55
52
  /#{Nuget::Version::VERSION_PATTERN}/o,
56
- latest_version.to_s
53
+ clean_version.to_s
57
54
  )
58
55
  end
59
56
 
60
57
  next req if new_req == req.fetch(:requirement)
61
58
 
62
- req.merge(requirement: new_req, source: updated_source)
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 })
63
68
  end
64
69
  end
65
70
 
@@ -68,17 +73,18 @@ module Dependabot
68
73
  sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
69
74
  attr_reader :requirements
70
75
 
71
- sig { returns(T.nilable(Dependabot::Nuget::Version)) }
72
- attr_reader :latest_version
73
-
74
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
75
- attr_reader :source_details
76
-
77
76
  sig { returns(T.class_of(Dependabot::Nuget::Version)) }
78
77
  def version_class
79
78
  Dependabot::Nuget::Version
80
79
  end
81
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
+
82
88
  sig { params(req_string: String).returns(String) }
83
89
  def update_wildcard_requirement(req_string)
84
90
  return req_string if req_string == "*-*"
@@ -88,21 +94,11 @@ module Dependabot
88
94
  precision = T.must(req_string.split("*").first).split(/\.|\-/).count
89
95
  wildcard_section = req_string.partition(/(?=[.\-]\*)/).last
90
96
 
91
- version_parts = T.must(latest_version).segments.first(precision)
97
+ version_parts = T.must(clean_version).segments.first(precision)
92
98
  version = version_parts.join(".")
93
99
 
94
100
  version + wildcard_section
95
101
  end
96
-
97
- sig { returns(T::Hash[Symbol, T.untyped]) }
98
- def updated_source
99
- {
100
- type: "nuget_repo",
101
- url: source_details&.fetch(:repo_url),
102
- nuspec_url: source_details&.fetch(:nuspec_url),
103
- source_url: source_details&.fetch(:source_url)
104
- }
105
- end
106
102
  end
107
103
  end
108
104
  end
@@ -1,7 +1,8 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
- require "dependabot/nuget/file_parser"
4
+ require "dependabot/nuget/analysis/analysis_json_reader"
5
+ require "dependabot/nuget/discovery/discovery_json_reader"
5
6
  require "dependabot/update_checkers"
6
7
  require "dependabot/update_checkers/base"
7
8
  require "sorbet-runtime"
@@ -11,38 +12,22 @@ module Dependabot
11
12
  class UpdateChecker < Dependabot::UpdateCheckers::Base
12
13
  extend T::Sig
13
14
 
14
- require_relative "update_checker/version_finder"
15
- require_relative "update_checker/property_updater"
16
15
  require_relative "update_checker/requirements_updater"
17
- require_relative "update_checker/dependency_finder"
18
-
19
- require_relative "native_update_checker/native_update_checker"
20
-
21
- PROPERTY_REGEX = /\$\((?<property>.*?)\)/
22
-
23
- sig { returns(T::Boolean) }
24
- def self.native_analysis_enabled?
25
- Dependabot::Experiments.enabled?(:nuget_native_analysis)
26
- end
27
16
 
28
17
  sig { override.returns(T.nilable(String)) }
29
18
  def latest_version
30
- return native_update_checker.latest_version if UpdateChecker.native_analysis_enabled?
31
-
32
19
  # No need to find latest version for transitive dependencies unless they have a vulnerability.
33
20
  return dependency.version if !dependency.top_level? && !vulnerable?
34
21
 
35
22
  # if no update sources have the requisite package, then we can only assume that the current version is correct
36
23
  @latest_version = T.let(
37
- latest_version_details&.fetch(:version)&.to_s || dependency.version,
24
+ update_analysis.dependency_analysis.updated_version,
38
25
  T.nilable(String)
39
26
  )
40
27
  end
41
28
 
42
29
  sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
43
30
  def latest_resolvable_version
44
- return native_update_checker.latest_resolvable_version if UpdateChecker.native_analysis_enabled?
45
-
46
31
  # We always want a full unlock since any package update could update peer dependencies as well.
47
32
  # To force a full unlock instead of an own unlock, we return nil.
48
33
  nil
@@ -50,232 +35,173 @@ module Dependabot
50
35
 
51
36
  sig { override.returns(Dependabot::Nuget::Version) }
52
37
  def lowest_security_fix_version
53
- return native_update_checker.lowest_security_fix_version if UpdateChecker.native_analysis_enabled?
54
-
55
- lowest_security_fix_version_details&.fetch(:version)
38
+ update_analysis.dependency_analysis.numeric_updated_version
56
39
  end
57
40
 
58
41
  sig { override.returns(T.nilable(Dependabot::Nuget::Version)) }
59
42
  def lowest_resolvable_security_fix_version
60
43
  return nil if version_comes_from_multi_dependency_property?
61
44
 
62
- lowest_security_fix_version
45
+ update_analysis.dependency_analysis.numeric_updated_version
63
46
  end
64
47
 
65
48
  sig { override.returns(NilClass) }
66
49
  def latest_resolvable_version_with_no_unlock
67
- return native_update_checker.latest_resolvable_version_with_no_unlock if UpdateChecker.native_analysis_enabled?
68
-
69
50
  # Irrelevant, since Nuget has a single dependency file
70
51
  nil
71
52
  end
72
53
 
73
54
  sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
74
55
  def updated_requirements
75
- return native_update_checker.updated_requirements if UpdateChecker.native_analysis_enabled?
76
-
56
+ dep_details = updated_dependency_details.find { |d| d.name.casecmp?(dependency.name) }
77
57
  RequirementsUpdater.new(
78
58
  requirements: dependency.requirements,
79
- latest_version: preferred_resolvable_version_details&.fetch(:version, nil)&.to_s,
80
- source_details: preferred_resolvable_version_details&.slice(:nuspec_url, :repo_url, :source_url)
59
+ dependency_details: dep_details
81
60
  ).updated_requirements
82
61
  end
83
62
 
84
63
  sig { returns(T::Boolean) }
85
64
  def up_to_date?
86
- return native_update_checker.up_to_date? if UpdateChecker.native_analysis_enabled?
87
-
88
- # No need to update transitive dependencies unless they have a vulnerability.
89
- return true if !dependency.top_level? && !vulnerable?
90
-
91
- # If any requirements have an uninterpolated property in them then
92
- # that property couldn't be found, and we assume that the dependency
93
- # is up-to-date
94
- return true unless requirements_unlocked_or_can_be?
95
-
96
- super
65
+ !update_analysis.dependency_analysis.can_update
97
66
  end
98
67
 
99
68
  sig { returns(T::Boolean) }
100
69
  def requirements_unlocked_or_can_be?
101
- # If any requirements have an uninterpolated property in them then
102
- # that property couldn't be found, and the requirement therefore
103
- # cannot be unlocked (since we can't update that property)
104
- dependency.requirements.none? do |req|
105
- req.fetch(:requirement)&.match?(PROPERTY_REGEX)
106
- end
70
+ update_analysis.dependency_analysis.can_update
107
71
  end
108
72
 
109
73
  private
110
74
 
111
- sig { returns(Dependabot::Nuget::NativeUpdateChecker) }
112
- def native_update_checker
113
- @native_update_checker ||=
114
- T.let(
115
- Dependabot::Nuget::NativeUpdateChecker.new(
116
- dependency: dependency,
117
- dependency_files: dependency_files,
118
- credentials: credentials,
119
- repo_contents_path: repo_contents_path,
120
- ignored_versions: ignored_versions,
121
- raise_on_ignored: raise_on_ignored,
122
- security_advisories: security_advisories,
123
- requirements_update_strategy: requirements_update_strategy,
124
- dependency_group: dependency_group,
125
- options: options
126
- ),
127
- T.nilable(Dependabot::Nuget::NativeUpdateChecker)
128
- )
75
+ sig { returns(String) }
76
+ def job_file_path
77
+ ENV.fetch("DEPENDABOT_JOB_PATH")
129
78
  end
130
79
 
131
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
132
- def preferred_resolvable_version_details
133
- # If this dependency is vulnerable, prefer trying to update to the
134
- # lowest_resolvable_security_fix_version. Otherwise update all the way
135
- # to the latest_resolvable_version.
136
- return lowest_security_fix_version_details if vulnerable?
137
-
138
- latest_version_details
80
+ sig { returns(AnalysisJsonReader) }
81
+ def update_analysis
82
+ @update_analysis ||= T.let(request_analysis, T.nilable(AnalysisJsonReader))
139
83
  end
140
84
 
141
- sig { override.returns(T::Boolean) }
142
- def latest_version_resolvable_with_full_unlock?
143
- if UpdateChecker.native_analysis_enabled?
144
- return native_update_checker.public_latest_version_resolvable_with_full_unlock?
145
- end
146
-
147
- # We always want a full unlock since any package update could update peer dependencies as well.
148
- return true unless version_comes_from_multi_dependency_property?
149
-
150
- property_updater.update_possible?
85
+ sig { returns(String) }
86
+ def dependency_file_path
87
+ d = File.join(Dir.tmpdir, "dependency")
88
+ FileUtils.mkdir_p(d)
89
+ File.join(d, "#{dependency.name}.json")
151
90
  end
152
91
 
153
- sig { override.returns(T::Array[Dependabot::Dependency]) }
154
- def updated_dependencies_after_full_unlock
155
- if UpdateChecker.native_analysis_enabled?
156
- return native_update_checker.public_updated_dependencies_after_full_unlock
92
+ sig { returns(T::Array[String]) }
93
+ def dependency_file_paths
94
+ dependency_files.map do |file|
95
+ DiscoveryJsonReader.dependency_file_path(
96
+ repo_contents_path: T.must(repo_contents_path),
97
+ dependency_file: file
98
+ )
157
99
  end
100
+ end
158
101
 
159
- return property_updater.updated_dependencies if version_comes_from_multi_dependency_property?
160
-
161
- puts "Finding updated dependencies for #{dependency.name}."
162
-
163
- updated_dependency = Dependency.new(
164
- name: dependency.name,
165
- version: latest_version,
166
- requirements: updated_requirements,
167
- previous_version: dependency.version,
168
- previous_requirements: dependency.requirements,
169
- package_manager: dependency.package_manager
102
+ sig { returns(AnalysisJsonReader) }
103
+ def request_analysis
104
+ discovery_file_path = DiscoveryJsonReader.get_discovery_json_path_for_dependency_file_paths(
105
+ dependency_file_paths
170
106
  )
171
- updated_dependencies = [updated_dependency]
172
- updated_dependencies += DependencyFinder.new(
173
- dependency: updated_dependency,
174
- dependency_files: dependency_files,
175
- ignored_versions: ignored_versions,
176
- credentials: credentials,
177
- repo_contents_path: @repo_contents_path
178
- ).updated_peer_dependencies
179
- updated_dependencies
180
- end
107
+ analysis_folder_path = AnalysisJsonReader.temp_directory
108
+
109
+ write_dependency_info
110
+
111
+ NativeHelpers.run_nuget_analyze_tool(job_path: job_file_path,
112
+ repo_root: T.must(repo_contents_path),
113
+ discovery_file_path: discovery_file_path,
114
+ dependency_file_path: dependency_file_path,
115
+ analysis_folder_path: analysis_folder_path,
116
+ credentials: credentials)
117
+
118
+ analysis_json = AnalysisJsonReader.analysis_json(dependency_name: dependency.name)
119
+
120
+ AnalysisJsonReader.new(analysis_json: T.must(analysis_json))
121
+ end
122
+
123
+ sig { void }
124
+ def write_dependency_info
125
+ dependency_info = {
126
+ Name: dependency.name,
127
+ Version: dependency.version.to_s,
128
+ IsVulnerable: vulnerable?,
129
+ IgnoredVersions: ignored_versions,
130
+ Vulnerabilities: security_advisories.map do |vulnerability|
131
+ {
132
+ DependencyName: vulnerability.dependency_name,
133
+ PackageManager: vulnerability.package_manager,
134
+ VulnerableVersions: vulnerability.vulnerable_versions.map(&:to_s),
135
+ SafeVersions: vulnerability.safe_versions.map(&:to_s)
136
+ }
137
+ end
138
+ }.to_json
139
+ dependency_directory = File.dirname(dependency_file_path)
181
140
 
182
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
183
- def preferred_version_details
184
- return lowest_security_fix_version_details if vulnerable?
141
+ begin
142
+ Dir.mkdir(dependency_directory)
143
+ rescue StandardError
144
+ nil?
145
+ end
185
146
 
186
- latest_version_details
147
+ Dependabot.logger.info("Writing dependency info: #{dependency_info}")
148
+ File.write(dependency_file_path, dependency_info)
187
149
  end
188
150
 
189
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
190
- def latest_version_details
191
- @latest_version_details ||=
192
- T.let(
193
- version_finder.latest_version_details,
194
- T.nilable(T::Hash[Symbol, T.untyped])
195
- )
151
+ sig { returns(Dependabot::FileParsers::Base::DependencySet) }
152
+ def discovered_dependencies
153
+ DiscoveryJsonReader.load_discovery_for_dependency_file_paths(dependency_file_paths).dependency_set
196
154
  end
197
155
 
198
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
199
- def lowest_security_fix_version_details
200
- @lowest_security_fix_version_details ||=
201
- T.let(
202
- version_finder.lowest_security_fix_version_details,
203
- T.nilable(T::Hash[Symbol, T.untyped])
204
- )
156
+ sig { override.returns(T::Boolean) }
157
+ def latest_version_resolvable_with_full_unlock?
158
+ # We always want a full unlock since any package update could update peer dependencies as well.
159
+ true
205
160
  end
206
161
 
207
- sig { returns(Dependabot::Nuget::UpdateChecker::VersionFinder) }
208
- def version_finder
209
- @version_finder ||=
210
- T.let(
211
- VersionFinder.new(
212
- dependency: dependency,
213
- dependency_files: dependency_files,
214
- credentials: credentials,
215
- ignored_versions: ignored_versions,
216
- raise_on_ignored: @raise_on_ignored,
217
- security_advisories: security_advisories,
218
- repo_contents_path: @repo_contents_path
219
- ),
220
- T.nilable(Dependabot::Nuget::UpdateChecker::VersionFinder)
221
- )
222
- end
162
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
163
+ def updated_dependencies_after_full_unlock
164
+ dependencies = discovered_dependencies.dependencies
165
+ updated_dependency_details.filter_map do |dependency_details|
166
+ dep = dependencies.find { |d| d.name.casecmp(dependency_details.name)&.zero? }
167
+ next unless dep
168
+
169
+ metadata = {}
170
+ # For peer dependencies, instruct updater to not directly update this dependency
171
+ metadata = { information_only: true } unless dependency.name.casecmp(dependency_details.name)&.zero?
172
+
173
+ # rebuild the new requirements with the updated dependency details
174
+ updated_reqs = dep.requirements.map do |r|
175
+ r = r.clone
176
+ r[:requirement] = dependency_details.version
177
+ r[:source] = {
178
+ type: "nuget_repo",
179
+ source_url: dependency_details.info_url
180
+ }
181
+ r
182
+ end
223
183
 
224
- sig { returns(Dependabot::Nuget::UpdateChecker::PropertyUpdater) }
225
- def property_updater
226
- @property_updater ||=
227
- T.let(
228
- PropertyUpdater.new(
229
- dependency: dependency,
230
- dependency_files: dependency_files,
231
- target_version_details: latest_version_details,
232
- credentials: credentials,
233
- ignored_versions: ignored_versions,
234
- raise_on_ignored: @raise_on_ignored,
235
- repo_contents_path: @repo_contents_path
236
- ),
237
- T.nilable(Dependabot::Nuget::UpdateChecker::PropertyUpdater)
184
+ Dependency.new(
185
+ name: dep.name,
186
+ version: dependency_details.version,
187
+ requirements: updated_reqs,
188
+ previous_version: dep.version,
189
+ previous_requirements: dep.requirements,
190
+ package_manager: dep.package_manager,
191
+ metadata: metadata
238
192
  )
239
- end
240
-
241
- sig { returns(T::Boolean) }
242
- def version_comes_from_multi_dependency_property?
243
- declarations_using_a_property.any? do |requirement|
244
- property_name = requirement.fetch(:metadata).fetch(:property_name)
245
-
246
- all_property_based_dependencies.any? do |dep|
247
- next false if dep.name == dependency.name
248
-
249
- dep.requirements.any? do |req|
250
- req.dig(:metadata, :property_name) == property_name
251
- end
252
- end
253
193
  end
254
194
  end
255
195
 
256
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
257
- def declarations_using_a_property
258
- @declarations_using_a_property ||=
259
- T.let(
260
- dependency.requirements
261
- .select { |req| req.dig(:metadata, :property_name) },
262
- T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
263
- )
196
+ sig { returns(T::Array[Dependabot::Nuget::DependencyDetails]) }
197
+ def updated_dependency_details
198
+ @updated_dependency_details ||= T.let(update_analysis.dependency_analysis.updated_dependencies,
199
+ T.nilable(T::Array[Dependabot::Nuget::DependencyDetails]))
264
200
  end
265
201
 
266
- sig { returns(T::Array[Dependabot::Dependency]) }
267
- def all_property_based_dependencies
268
- @all_property_based_dependencies ||=
269
- T.let(
270
- Nuget::FileParser.new(
271
- dependency_files: dependency_files,
272
- repo_contents_path: repo_contents_path,
273
- source: nil
274
- ).parse.select do |dep|
275
- dep.requirements.any? { |req| req.dig(:metadata, :property_name) }
276
- end,
277
- T.nilable(T::Array[Dependabot::Dependency])
278
- )
202
+ sig { returns(T::Boolean) }
203
+ def version_comes_from_multi_dependency_property?
204
+ update_analysis.dependency_analysis.version_comes_from_multi_dependency_property
279
205
  end
280
206
  end
281
207
  end