dependabot-nuget 0.287.0 → 0.289.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/.gitignore +1 -0
- data/helpers/lib/NuGetUpdater/Directory.Build.targets +17 -0
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +26 -17
- data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +7 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +3 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +88 -47
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +31 -16
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementArrayConverter.cs +39 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/ShellGitCommandHandler.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.props +7 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +64 -53
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DotNetToolsJsonDiscovery.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/GlobalJsonDiscovery.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +17 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +3 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +3 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +429 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +12 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/JsonBuildFile.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/CompatabilityChecker.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +7 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +23 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +43 -58
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/TargetFrameworkReporter.targets +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +13 -43
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/DotNetToolsJsonUpdater.cs +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/GlobalJsonUpdater.cs +5 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +40 -33
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +12 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/CollectionExtensions.cs +17 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ConsoleLogger.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +19 -19
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +11 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +74 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathComparer.cs +31 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +46 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +96 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +135 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +71 -38
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +66 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +11 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +808 -222
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +477 -97
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +5 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +494 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +46 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +401 -77
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +35 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +60 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +3 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestLogger.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/BindingRedirectsTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +8 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +40 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/AssertEx.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +12 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +8 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +49 -3
- data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +3 -1
- data/lib/dependabot/nuget/file_fetcher.rb +12 -393
- data/lib/dependabot/nuget/file_parser.rb +23 -54
- data/lib/dependabot/nuget/file_updater.rb +21 -16
- data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +2 -9
- data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +183 -80
- data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +25 -3
- data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +1 -11
- data/lib/dependabot/nuget/native_helpers.rb +13 -4
- data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +17 -4
- metadata +15 -12
- data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Packages.props +0 -29
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +0 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs +0 -69
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscoveryResult.cs +0 -11
- data/lib/dependabot/nuget/file_fetcher/import_paths_finder.rb +0 -73
- data/lib/dependabot/nuget/file_fetcher/sln_project_paths_finder.rb +0 -60
- data/lib/dependabot/nuget/native_discovery/native_directory_packages_props_discovery.rb +0 -44
@@ -1,9 +1,10 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/file_fetchers"
|
5
5
|
require "dependabot/file_fetchers/base"
|
6
|
-
require "dependabot/nuget/
|
6
|
+
require "dependabot/nuget/native_discovery/native_discovery_json_reader"
|
7
|
+
require "dependabot/nuget/native_helpers"
|
7
8
|
require "set"
|
8
9
|
require "sorbet-runtime"
|
9
10
|
|
@@ -13,410 +14,28 @@ module Dependabot
|
|
13
14
|
extend T::Sig
|
14
15
|
extend T::Helpers
|
15
16
|
|
16
|
-
require_relative "file_fetcher/import_paths_finder"
|
17
|
-
require_relative "file_fetcher/sln_project_paths_finder"
|
18
|
-
|
19
|
-
BUILD_FILE_NAMES = /^Directory\.Build\.(props|targets)$/i # Directory.Build.props, Directory.Build.targets
|
20
|
-
|
21
17
|
sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
|
22
18
|
def self.required_files_in?(filenames)
|
23
|
-
return true if filenames.any? { |f| f.match?(/^packages\.config$/i) }
|
24
|
-
return true if filenames.any? { |f| f.end_with?(".sln") }
|
25
|
-
return true if filenames.any? { |f| f.match?("^src$") }
|
26
|
-
return true if filenames.any? { |f| f.end_with?(".proj") }
|
27
|
-
|
28
19
|
filenames.any? { |name| name.match?(/\.(cs|vb|fs)proj$/) }
|
29
20
|
end
|
30
21
|
|
31
22
|
sig { override.returns(String) }
|
32
23
|
def self.required_files_message
|
33
|
-
"Repo must contain
|
34
|
-
end
|
35
|
-
|
36
|
-
sig do
|
37
|
-
override
|
38
|
-
.params(
|
39
|
-
source: Dependabot::Source,
|
40
|
-
credentials: T::Array[Credential],
|
41
|
-
repo_contents_path: T.nilable(String),
|
42
|
-
options: T::Hash[String, String]
|
43
|
-
).void
|
44
|
-
end
|
45
|
-
def initialize(source:, credentials:, repo_contents_path: nil, options: {})
|
46
|
-
super
|
47
|
-
|
48
|
-
@sln_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
49
|
-
@sln_project_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
50
|
-
@project_files = T.let([], T::Array[Dependabot::DependencyFile])
|
51
|
-
@fetched_files = T.let({}, T::Hash[String, T::Array[Dependabot::DependencyFile]])
|
52
|
-
@nuget_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
53
|
-
@packages_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
54
|
-
@assembly_binding_redirect_config_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
55
|
-
@packages_lock_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
|
24
|
+
"Repo must contain .(cs|vb|fs)proj file."
|
56
25
|
end
|
57
26
|
|
58
27
|
sig { override.returns(T::Array[DependencyFile]) }
|
59
28
|
def fetch_files
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
*packages_config_files,
|
65
|
-
*assembly_binding_redirect_config_files,
|
66
|
-
*nuget_config_files,
|
67
|
-
*packages_lock_files,
|
68
|
-
global_json,
|
69
|
-
dotnet_tools_json,
|
70
|
-
packages_props
|
71
|
-
].compact
|
72
|
-
|
73
|
-
# dedup files based on their absolute path
|
74
|
-
fetched_files = fetched_files.uniq do |fetched_file|
|
75
|
-
Pathname.new(fetched_file.directory).join(fetched_file.name).cleanpath.to_path
|
76
|
-
end
|
77
|
-
|
78
|
-
if project_files.none? && packages_config_files.none?
|
79
|
-
raise T.must(@missing_sln_project_file_errors.first) if @missing_sln_project_file_errors&.any?
|
80
|
-
|
81
|
-
raise_dependency_file_not_found
|
82
|
-
end
|
83
|
-
|
84
|
-
fetched_files
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
90
|
-
def project_files
|
91
|
-
return @project_files if @project_files.any?
|
92
|
-
|
93
|
-
@project_files =
|
94
|
-
begin
|
95
|
-
project_files = []
|
96
|
-
project_files += csproj_file
|
97
|
-
project_files += vbproj_file
|
98
|
-
project_files += fsproj_file
|
99
|
-
project_files += sln_project_files
|
100
|
-
project_files += proj_files
|
101
|
-
project_files += project_files.filter_map do |f|
|
102
|
-
named_file_up_tree_from_project_file(f, "Directory.Packages.props")
|
103
|
-
end
|
104
|
-
project_files
|
105
|
-
end
|
106
|
-
rescue Octokit::NotFound, Gitlab::Error::NotFound
|
107
|
-
raise_dependency_file_not_found
|
108
|
-
end
|
109
|
-
|
110
|
-
sig { returns(T.noreturn) }
|
111
|
-
def raise_dependency_file_not_found
|
112
|
-
raise(
|
113
|
-
Dependabot::DependencyFileNotFound.new(
|
114
|
-
File.join(directory, "*.(sln|csproj|vbproj|fsproj|proj)"),
|
115
|
-
"Unable to find `*.sln`, `*.(cs|vb|fs)proj`, or `*.proj` in directory `#{directory}`"
|
116
|
-
)
|
29
|
+
discovery_json_reader = NativeDiscoveryJsonReader.run_discovery_in_directory(
|
30
|
+
repo_contents_path: T.must(repo_contents_path),
|
31
|
+
directory: directory,
|
32
|
+
credentials: credentials
|
117
33
|
)
|
118
|
-
end
|
119
|
-
|
120
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
121
|
-
def packages_config_files
|
122
|
-
return @packages_config_files if @packages_config_files
|
123
|
-
|
124
|
-
imported_project_files = imported_property_files.filter { |f| f.name.match?(/\.(cs|vb|fs)proj$/) }
|
125
|
-
|
126
|
-
@packages_config_files = [*project_files, *imported_project_files].filter_map do |f|
|
127
|
-
named_file_next_to_project_file(f, "packages.config")
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
132
|
-
def assembly_binding_redirect_config_files
|
133
|
-
return @assembly_binding_redirect_config_files if @assembly_binding_redirect_config_files
|
134
|
-
|
135
|
-
candidate_paths =
|
136
|
-
[*project_files.map { |f| File.dirname(f.name) }, "."].uniq
|
137
|
-
|
138
|
-
# Assembly binding redirects can appear in any app/web.config file for a .NET Framework project
|
139
|
-
# https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions#specify-assembly-binding-in-configuration-files
|
140
|
-
@assembly_binding_redirect_config_files =
|
141
|
-
candidate_paths.filter_map do |dir|
|
142
|
-
file = repo_contents(dir: dir)
|
143
|
-
.find { |f| f.name.match?(/^(app|web)\.config$/i) }
|
144
|
-
fetch_file_from_host(File.join(dir, file.name)) if file
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
149
|
-
sig { returns(T.nilable(T::Array[T.untyped])) }
|
150
|
-
def sln_file_names
|
151
|
-
sln_files = repo_contents.select { |f| f.name.end_with?(".sln") }
|
152
|
-
src_dir = repo_contents.any? { |f| f.name == "src" && f.type == "dir" }
|
153
|
-
|
154
|
-
# If there are no sln files but there is a src directory, check that dir
|
155
|
-
if sln_files.none? && src_dir
|
156
|
-
sln_files = repo_contents(dir: "src")
|
157
|
-
.select { |f| f.name.end_with?(".sln") }.map(&:dup)
|
158
|
-
.map { |file| file.tap { |f| f.name = "src/" + f.name } }
|
159
|
-
end
|
160
|
-
|
161
|
-
# Return `nil` if no sln files were found
|
162
|
-
return if sln_files.none?
|
163
|
-
|
164
|
-
sln_files.map(&:name)
|
165
|
-
end
|
166
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
167
|
-
|
168
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
169
|
-
def directory_build_files
|
170
|
-
@directory_build_files ||= T.let(fetch_directory_build_files, T.nilable(T::Array[Dependabot::DependencyFile]))
|
171
|
-
end
|
172
|
-
|
173
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
174
|
-
def fetch_directory_build_files
|
175
|
-
attempted_dirs = T.let([], T::Array[Pathname])
|
176
|
-
directory_build_files = T.let([], T::Array[Dependabot::DependencyFile])
|
177
|
-
directory_path = Pathname.new(directory)
|
178
|
-
|
179
|
-
# find all build files (Directory.Build.props/.targets) relative to the given project file
|
180
|
-
project_files.map { |f| Pathname.new(f.directory).join(f.name).dirname }.uniq.each do |dir|
|
181
|
-
# Simulate MSBuild walking up the directory structure looking for a file
|
182
|
-
dir.descend.each do |possible_dir|
|
183
|
-
break if attempted_dirs.include?(possible_dir)
|
184
|
-
|
185
|
-
attempted_dirs << possible_dir
|
186
|
-
relative_possible_dir = Pathname.new(possible_dir).relative_path_from(directory_path).to_s
|
187
|
-
build_files = repo_contents(dir: relative_possible_dir).select { |f| f.name.match?(BUILD_FILE_NAMES) }
|
188
|
-
directory_build_files += build_files.map do |file|
|
189
|
-
possible_file = File.join(relative_possible_dir, file.name).delete_prefix("/")
|
190
|
-
fetch_file_from_host(possible_file)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
directory_build_files
|
196
|
-
end
|
197
|
-
|
198
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
199
|
-
def sln_project_files
|
200
|
-
return [] unless sln_files
|
201
|
-
|
202
|
-
@sln_project_files ||=
|
203
|
-
begin
|
204
|
-
paths = T.must(sln_files).flat_map do |sln_file|
|
205
|
-
SlnProjectPathsFinder
|
206
|
-
.new(sln_file: sln_file)
|
207
|
-
.project_paths
|
208
|
-
end
|
209
|
-
|
210
|
-
paths.filter_map do |path|
|
211
|
-
fetch_file_from_host(path)
|
212
|
-
rescue Dependabot::DependencyFileNotFound => e
|
213
|
-
@missing_sln_project_file_errors ||= T.let([], T.nilable(T::Array[Dependabot::DependencyFileNotFound]))
|
214
|
-
@missing_sln_project_file_errors << e
|
215
|
-
# Don't worry about missing files too much for now (at least
|
216
|
-
# until we start resolving properties)
|
217
|
-
nil
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
sig { returns(T.nilable(T::Array[Dependabot::DependencyFile])) }
|
223
|
-
def sln_files
|
224
|
-
return unless sln_file_names
|
225
|
-
|
226
|
-
@sln_files ||=
|
227
|
-
sln_file_names
|
228
|
-
&.map { |sln_file_name| fetch_file_from_host(sln_file_name) }
|
229
|
-
&.select { |file| file.content&.valid_encoding? }
|
230
|
-
end
|
231
|
-
|
232
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
233
|
-
def csproj_file
|
234
|
-
@csproj_file ||= T.let(find_and_fetch_with_suffix(".csproj"), T.nilable(T::Array[Dependabot::DependencyFile]))
|
235
|
-
end
|
236
|
-
|
237
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
238
|
-
def vbproj_file
|
239
|
-
@vbproj_file ||= T.let(find_and_fetch_with_suffix(".vbproj"), T.nilable(T::Array[Dependabot::DependencyFile]))
|
240
|
-
end
|
241
|
-
|
242
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
243
|
-
def fsproj_file
|
244
|
-
@fsproj_file ||= T.let(find_and_fetch_with_suffix(".fsproj"), T.nilable(T::Array[Dependabot::DependencyFile]))
|
245
|
-
end
|
246
|
-
|
247
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
248
|
-
def proj_files
|
249
|
-
@proj_files ||= T.let(find_and_fetch_with_suffix(".proj"), T.nilable(T::Array[Dependabot::DependencyFile]))
|
250
|
-
end
|
251
|
-
|
252
|
-
sig { params(suffix: String).returns(T::Array[Dependabot::DependencyFile]) }
|
253
|
-
def find_and_fetch_with_suffix(suffix)
|
254
|
-
repo_contents.select { |f| f.name.end_with?(suffix) }.map { |f| fetch_file_from_host(f.name) }
|
255
|
-
end
|
256
|
-
|
257
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
258
|
-
def nuget_config_files
|
259
|
-
return @nuget_config_files if @nuget_config_files
|
260
|
-
|
261
|
-
@nuget_config_files = [*project_files.map do |f|
|
262
|
-
named_file_up_tree_from_project_file(f, "nuget.config")
|
263
|
-
end].compact.uniq
|
264
|
-
@nuget_config_files
|
265
|
-
end
|
266
|
-
|
267
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
268
|
-
def packages_lock_files
|
269
|
-
return @packages_lock_files if @packages_lock_files
|
270
|
-
|
271
|
-
candidate_paths =
|
272
|
-
[*project_files.map { |f| File.dirname(f.name) }, "."].uniq
|
273
|
-
|
274
|
-
@packages_lock_files =
|
275
|
-
candidate_paths.filter_map do |dir|
|
276
|
-
file = repo_contents(dir: dir)
|
277
|
-
.find { |f| f.name.casecmp("packages.lock.json").zero? }
|
278
|
-
fetch_file_from_host(File.join(dir, file.name)) if file
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
sig do
|
283
|
-
params(
|
284
|
-
project_file: Dependabot::DependencyFile,
|
285
|
-
expected_file_name: String
|
286
|
-
)
|
287
|
-
.returns(T.nilable(Dependabot::DependencyFile))
|
288
|
-
end
|
289
|
-
def named_file_up_tree_from_project_file(project_file, expected_file_name)
|
290
|
-
found_expected_file = T.let(nil, T.nilable(Dependabot::DependencyFile))
|
291
|
-
directory_path = Pathname.new(directory)
|
292
|
-
full_project_dir = Pathname.new(project_file.directory).join(project_file.name).dirname
|
293
|
-
full_project_dir.ascend.each do |base|
|
294
|
-
break if found_expected_file
|
295
|
-
|
296
|
-
candidate_file_path = Pathname.new(base).join(expected_file_name).cleanpath.to_path
|
297
|
-
candidate_directory = Pathname.new(File.dirname(candidate_file_path))
|
298
|
-
relative_candidate_directory = candidate_directory.relative_path_from(directory_path)
|
299
|
-
candidate_file = repo_contents(dir: relative_candidate_directory).find do |f|
|
300
|
-
f.name.casecmp?(expected_file_name)
|
301
|
-
end
|
302
|
-
if candidate_file
|
303
|
-
found_expected_file = fetch_file_from_host(File.join(relative_candidate_directory,
|
304
|
-
candidate_file.name))
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
found_expected_file
|
309
|
-
end
|
310
|
-
|
311
|
-
sig do
|
312
|
-
params(
|
313
|
-
project_file: Dependabot::DependencyFile,
|
314
|
-
expected_file_name: String
|
315
|
-
)
|
316
|
-
.returns(T.nilable(Dependabot::DependencyFile))
|
317
|
-
end
|
318
|
-
def named_file_next_to_project_file(project_file, expected_file_name)
|
319
|
-
found_expected_file = T.let(nil, T.nilable(Dependabot::DependencyFile))
|
320
|
-
directory_path = Pathname.new(directory)
|
321
|
-
full_project_dir = Pathname.new(project_file.directory).join(project_file.name).dirname
|
322
|
-
|
323
|
-
candidate_file_path = Pathname.new(full_project_dir).join(expected_file_name).cleanpath.to_path
|
324
|
-
candidate_directory = Pathname.new(File.dirname(candidate_file_path))
|
325
|
-
relative_candidate_directory = candidate_directory.relative_path_from(directory_path)
|
326
|
-
candidate_file = repo_contents(dir: relative_candidate_directory).find do |f|
|
327
|
-
f.name.casecmp?(expected_file_name)
|
328
|
-
end
|
329
|
-
if candidate_file
|
330
|
-
found_expected_file = fetch_file_from_host(File.join(relative_candidate_directory,
|
331
|
-
candidate_file.name))
|
332
|
-
end
|
333
|
-
|
334
|
-
found_expected_file
|
335
|
-
end
|
336
|
-
|
337
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
338
|
-
def global_json
|
339
|
-
@global_json ||= T.let(fetch_file_if_present("global.json"), T.nilable(Dependabot::DependencyFile))
|
340
|
-
end
|
341
|
-
|
342
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
343
|
-
def dotnet_tools_json
|
344
|
-
@dotnet_tools_json ||= T.let(fetch_file_if_present(".config/dotnet-tools.json"),
|
345
|
-
T.nilable(Dependabot::DependencyFile))
|
346
|
-
end
|
347
|
-
|
348
|
-
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
349
|
-
def packages_props
|
350
|
-
@packages_props ||= T.let(fetch_file_if_present("Packages.props"), T.nilable(Dependabot::DependencyFile))
|
351
|
-
end
|
352
|
-
|
353
|
-
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
354
|
-
def imported_property_files
|
355
|
-
imported_property_files = T.let([], T::Array[Dependabot::DependencyFile])
|
356
|
-
|
357
|
-
files = [*project_files, *directory_build_files]
|
358
|
-
|
359
|
-
files.each do |proj_file|
|
360
|
-
previously_fetched_files = project_files + imported_property_files
|
361
|
-
imported_property_files +=
|
362
|
-
fetch_imported_property_files(
|
363
|
-
file: proj_file,
|
364
|
-
previously_fetched_files: previously_fetched_files
|
365
|
-
)
|
366
|
-
end
|
367
|
-
|
368
|
-
imported_property_files
|
369
|
-
end
|
370
|
-
|
371
|
-
sig do
|
372
|
-
params(
|
373
|
-
file: Dependabot::DependencyFile,
|
374
|
-
previously_fetched_files: T::Array[Dependabot::DependencyFile]
|
375
|
-
)
|
376
|
-
.returns(T::Array[Dependabot::DependencyFile])
|
377
|
-
end
|
378
|
-
def fetch_imported_property_files(file:, previously_fetched_files:)
|
379
|
-
file_id = file.directory + "/" + file.name
|
380
|
-
|
381
|
-
if @fetched_files[file_id]
|
382
|
-
T.must(@fetched_files[file_id])
|
383
|
-
else
|
384
|
-
paths =
|
385
|
-
ImportPathsFinder.new(project_file: file).import_paths +
|
386
|
-
ImportPathsFinder.new(project_file: file).project_reference_paths +
|
387
|
-
ImportPathsFinder.new(project_file: file).project_file_paths
|
388
|
-
|
389
|
-
# Initialize a set to hold fetched files temporarily to avoid duplicates
|
390
|
-
fetched_files_set = Set.new([file])
|
391
|
-
|
392
|
-
paths.each do |path|
|
393
|
-
next if previously_fetched_files.map(&:name).include?(path)
|
394
|
-
next if file.name == path
|
395
|
-
next if path.include?("$(")
|
396
|
-
|
397
|
-
begin
|
398
|
-
fetched_file = fetch_file_from_host(path)
|
399
|
-
grandchild_property_files = fetch_imported_property_files(
|
400
|
-
file: fetched_file,
|
401
|
-
previously_fetched_files: previously_fetched_files + [file]
|
402
|
-
)
|
403
|
-
|
404
|
-
# Add fetched file and grandchild property files to the set
|
405
|
-
fetched_files_set << fetched_file
|
406
|
-
fetched_files_set.merge(grandchild_property_files)
|
407
|
-
rescue Dependabot::DependencyFileNotFound
|
408
|
-
# Don't worry about missing files, just skip them for now
|
409
|
-
Dependabot.logger.info("unable to find expected file #{file.name}")
|
410
|
-
nil
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
# Convert the set to an array and cache the fetched files
|
415
|
-
fetched_files = fetched_files_set.to_a
|
416
|
-
@fetched_files[file_id] = fetched_files
|
417
34
|
|
418
|
-
|
419
|
-
|
35
|
+
NativeDiscoveryJsonReader.debug_report_discovery_files(error_if_missing: false)
|
36
|
+
discovery_json_reader.dependency_file_paths.map do |p|
|
37
|
+
relative_path = Pathname.new(p).relative_path_from(directory).to_path
|
38
|
+
fetch_file_from_host(relative_path)
|
420
39
|
end
|
421
40
|
end
|
422
41
|
end
|
@@ -16,73 +16,42 @@ module Dependabot
|
|
16
16
|
extend T::Sig
|
17
17
|
|
18
18
|
require "dependabot/file_parsers/base/dependency_set"
|
19
|
-
require_relative "cache_manager"
|
20
|
-
|
21
|
-
sig { returns(T::Hash[String, T::Array[Dependabot::Dependency]]) }
|
22
|
-
def self.file_dependency_cache
|
23
|
-
T.let(CacheManager.cache("file_parser.parse"), T::Hash[String, T::Array[Dependabot::Dependency]])
|
24
|
-
end
|
25
19
|
|
26
20
|
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
27
21
|
def parse
|
28
|
-
|
29
|
-
|
30
|
-
key = NativeDiscoveryJsonReader.create_cache_key(dependency_files)
|
31
|
-
workspace_path = source&.directory || "/"
|
32
|
-
self.class.file_dependency_cache[key] ||= begin
|
33
|
-
# run discovery for the repo
|
34
|
-
discovery_json_path = NativeDiscoveryJsonReader.create_discovery_file_path_from_dependency_files(
|
35
|
-
dependency_files
|
36
|
-
)
|
37
|
-
NativeHelpers.run_nuget_discover_tool(repo_root: T.must(repo_contents_path),
|
38
|
-
workspace_path: workspace_path,
|
39
|
-
output_path: discovery_json_path,
|
40
|
-
credentials: credentials)
|
41
|
-
|
42
|
-
discovery_json = NativeDiscoveryJsonReader.discovery_json_from_path(discovery_json_path)
|
43
|
-
return [] unless discovery_json
|
44
|
-
|
45
|
-
Dependabot.logger.info("Discovery JSON content: #{discovery_json.content}")
|
46
|
-
discovery_json_reader = NativeDiscoveryJsonReader.new(
|
47
|
-
discovery_json: discovery_json
|
48
|
-
)
|
49
|
-
|
50
|
-
# cache discovery results
|
51
|
-
NativeDiscoveryJsonReader.set_discovery_from_dependency_files(dependency_files: dependency_files,
|
52
|
-
discovery: discovery_json_reader)
|
53
|
-
discovery_json_reader.dependency_set.dependencies
|
54
|
-
end
|
55
|
-
|
56
|
-
T.must(self.class.file_dependency_cache[key])
|
22
|
+
dependencies
|
57
23
|
end
|
58
24
|
|
59
25
|
private
|
60
26
|
|
61
|
-
sig { returns(T::Array[Dependabot::
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
dependency_files.select do |df|
|
75
|
-
df.name.match?(projectfile)
|
76
|
-
end
|
27
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
28
|
+
def dependencies
|
29
|
+
@dependencies ||= T.let(begin
|
30
|
+
NativeDiscoveryJsonReader.debug_report_discovery_files(error_if_missing: true)
|
31
|
+
directory = source&.directory || "/"
|
32
|
+
discovery_json_reader = NativeDiscoveryJsonReader.run_discovery_in_directory(
|
33
|
+
repo_contents_path: T.must(repo_contents_path),
|
34
|
+
directory: directory,
|
35
|
+
credentials: credentials
|
36
|
+
)
|
37
|
+
discovery_json_reader.dependency_set.dependencies
|
38
|
+
end, T.nilable(T::Array[Dependabot::Dependency]))
|
77
39
|
end
|
78
40
|
|
79
41
|
sig { override.void }
|
80
42
|
def check_required_files
|
81
|
-
|
43
|
+
requirement_files = dependencies.flat_map do |dep|
|
44
|
+
dep.requirements.map { |r| T.let(r.fetch(:file), String) }
|
45
|
+
end.uniq
|
46
|
+
|
47
|
+
project_files = requirement_files.select { |f| File.basename(f).match?(/\.(cs|vb|fs)proj$/) }
|
48
|
+
global_json_file = requirement_files.select { |f| File.basename(f) == "global.json" }
|
49
|
+
dotnet_tools_json_file = requirement_files.select { |f| File.basename(f) == "dotnet-tools.json" }
|
50
|
+
return if project_files.any? || global_json_file.any? || dotnet_tools_json_file.any?
|
82
51
|
|
83
52
|
raise Dependabot::DependencyFileNotFound.new(
|
84
|
-
"*.(cs|vb|fs)proj
|
85
|
-
"No project file
|
53
|
+
"*.(cs|vb|fs)proj",
|
54
|
+
"No project file."
|
86
55
|
)
|
87
56
|
end
|
88
57
|
end
|
@@ -57,7 +57,12 @@ module Dependabot
|
|
57
57
|
try_update_projects(dependency) || try_update_json(dependency)
|
58
58
|
end
|
59
59
|
updated_files = dependency_files.filter_map do |f|
|
60
|
-
|
60
|
+
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
|
61
|
+
repo_contents_path: T.must(repo_contents_path),
|
62
|
+
dependency_file: f
|
63
|
+
)
|
64
|
+
dependency_file_path = File.join(repo_contents_path, dependency_file_path)
|
65
|
+
updated_content = File.read(dependency_file_path)
|
61
66
|
next if updated_content == f.content
|
62
67
|
|
63
68
|
normalized_content = normalize_content(f, updated_content)
|
@@ -92,7 +97,11 @@ module Dependabot
|
|
92
97
|
# run update for each project file
|
93
98
|
project_files.each do |project_file|
|
94
99
|
project_dependencies = project_dependencies(project_file)
|
95
|
-
|
100
|
+
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
|
101
|
+
repo_contents_path: T.must(repo_contents_path),
|
102
|
+
dependency_file: project_file
|
103
|
+
)
|
104
|
+
proj_path = dependency_file_path
|
96
105
|
|
97
106
|
next unless project_dependencies.any? { |dep| dep.name.casecmp?(dependency.name) }
|
98
107
|
|
@@ -119,7 +128,11 @@ module Dependabot
|
|
119
128
|
|
120
129
|
# We just need to feed the updater a project file, grab the first
|
121
130
|
project_file = T.must(project_files.first)
|
122
|
-
|
131
|
+
dependency_file_path = NativeDiscoveryJsonReader.dependency_file_path(
|
132
|
+
repo_contents_path: T.must(repo_contents_path),
|
133
|
+
dependency_file: project_file
|
134
|
+
)
|
135
|
+
proj_path = dependency_file_path
|
123
136
|
|
124
137
|
return false unless repo_contents_path
|
125
138
|
|
@@ -157,8 +170,11 @@ module Dependabot
|
|
157
170
|
|
158
171
|
sig { returns(T.nilable(NativeWorkspaceDiscovery)) }
|
159
172
|
def workspace
|
160
|
-
|
161
|
-
|
173
|
+
dependency_file_paths = dependency_files.map do |f|
|
174
|
+
NativeDiscoveryJsonReader.dependency_file_path(repo_contents_path: T.must(repo_contents_path),
|
175
|
+
dependency_file: f)
|
176
|
+
end
|
177
|
+
NativeDiscoveryJsonReader.load_discovery_for_dependency_file_paths(dependency_file_paths).workspace_discovery
|
162
178
|
end
|
163
179
|
|
164
180
|
sig { params(project_file: Dependabot::DependencyFile).returns(T::Array[String]) }
|
@@ -215,17 +231,6 @@ module Dependabot
|
|
215
231
|
end
|
216
232
|
# rubocop:enable Metrics/PerceivedComplexity
|
217
233
|
|
218
|
-
sig { params(dependency_file: Dependabot::DependencyFile).returns(String) }
|
219
|
-
def dependency_file_path(dependency_file)
|
220
|
-
if dependency_file.directory.start_with?(T.must(repo_contents_path))
|
221
|
-
File.join(dependency_file.directory, dependency_file.name)
|
222
|
-
else
|
223
|
-
file_directory = dependency_file.directory
|
224
|
-
file_directory = file_directory[1..-1] if file_directory.start_with?("/")
|
225
|
-
File.join(repo_contents_path || "", file_directory, dependency_file.name)
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
234
|
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
230
235
|
def project_files
|
231
236
|
dependency_files.select { |df| df.name.match?(/\.(cs|vb|fs)proj$/) }
|
@@ -41,7 +41,7 @@ module Dependabot
|
|
41
41
|
attr_reader :dependencies
|
42
42
|
|
43
43
|
sig { overridable.returns(Dependabot::FileParsers::Base::DependencySet) }
|
44
|
-
def dependency_set # rubocop:disable Metrics/PerceivedComplexity
|
44
|
+
def dependency_set # rubocop:disable Metrics/PerceivedComplexity
|
45
45
|
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
|
46
46
|
|
47
47
|
file_name = Pathname.new(file_path).cleanpath.to_path
|
@@ -65,14 +65,7 @@ module Dependabot
|
|
65
65
|
# Exclude any dependencies which reference an item type
|
66
66
|
next if dependency.name.include?("@(")
|
67
67
|
|
68
|
-
|
69
|
-
if dependency.type == "PackagesConfig"
|
70
|
-
dir_name = File.dirname(file_name)
|
71
|
-
dependency_file_name = "packages.config"
|
72
|
-
dependency_file_name = File.join(dir_name, "packages.config") unless dir_name == "."
|
73
|
-
end
|
74
|
-
|
75
|
-
dependency_set << build_dependency(dependency_file_name, dependency)
|
68
|
+
dependency_set << build_dependency(file_name, dependency)
|
76
69
|
end
|
77
70
|
|
78
71
|
dependency_set
|