dependabot-nuget 0.242.0 → 0.242.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11b0607da6a75d27dbe0c012d5b3917a226fd3da340cbcc59bf70dc1ab49dea3
4
- data.tar.gz: f757ea68e946791be5d44df566a91dff248f98c60be84253a25d399c24b881bd
3
+ metadata.gz: 1a49c3bda283658e65f9a37cf33e5b4855048bf2673bcfdcde4bb2e39d00d68e
4
+ data.tar.gz: 340fb04884786613bcbf75e25f7b51be9e662d26211418804965162df2c95c2a
5
5
  SHA512:
6
- metadata.gz: cce478626cb19d1d3daec2b23b2448445ddbf02fde1ffa80cd1372600852cb9e7c5fc2026303f9dfb8de3938870db16a2b531c04b160ede96c7c473bb673b3e3
7
- data.tar.gz: 9f084e5dfc866baa1b38cb01d2a55a9c6738b1e06703961fb33676353e4fda8095c36a951bb0a3515c503fe351582089b93d0faeac709e3e3e4f3706b158ec09
6
+ metadata.gz: 55e5a6b6949b5d30cfd95fb8ac185e9ccad548e0f8cc073237181c8a99e76252602920f6ff4cce68afb8310b4e358a7191ff4c9fe1ef27e92147529eb6c0012a
7
+ data.tar.gz: ea153c1649add8848551c6a54577beb7fa554f557275d1ed09928d741bc5ded5a1bfe7ed39561592bda152d8ded72f4081d30da3fcd748500f5d887825c27eb9
@@ -263,7 +263,7 @@ internal static partial class MSBuildHelper
263
263
  try
264
264
  {
265
265
  var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
266
- var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", $"build \"{tempProjectPath}\"");
266
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", $"restore \"{tempProjectPath}\"");
267
267
 
268
268
  // NU1608: Detected package version outside of dependency constraint
269
269
 
@@ -308,6 +308,7 @@ internal static partial class MSBuildHelper
308
308
  <PropertyGroup>
309
309
  <TargetFramework>{targetFramework}</TargetFramework>
310
310
  <GenerateDependencyFile>true</GenerateDependencyFile>
311
+ <RunAnalyzers>false</RunAnalyzers>
311
312
  </PropertyGroup>
312
313
  <ItemGroup>
313
314
  {packageReferences}
@@ -187,6 +187,69 @@ public class SdkPackageUpdaterTests
187
187
  "Newtonsoft.Json", "12.0.1", "13.0.1", false // isTransitive
188
188
  };
189
189
 
190
+ // Make sure we don't update if there are incoherent versions
191
+ yield return new object[] {
192
+ new []
193
+ {
194
+ (Path: "src/Project.csproj", Content: """
195
+ <Project Sdk="Microsoft.NET.Sdk">
196
+ <PropertyGroup>
197
+ <TargetFramework>netcoreapp2.1</TargetFramework>
198
+ </PropertyGroup>
199
+ <ItemGroup>
200
+ <PackageReference Include="Microsoft.Extensions.Primitives" Version="2.2.0" />
201
+ <PackageReference Include="Microsoft.Extensions.Options" Version="2.2.0" />
202
+ <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" />
203
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
204
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
205
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
206
+ <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.0" />
207
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
208
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
209
+ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
210
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" />
211
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.0" />
212
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="2.2.0" />
213
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="2.2.0" />
214
+ <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
215
+ <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" />
216
+ <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
217
+ </ItemGroup>
218
+ </Project>
219
+ """)
220
+ }, // starting contents
221
+ new []
222
+ {
223
+ (Path: "src/Project.csproj", Content: """
224
+ <Project Sdk="Microsoft.NET.Sdk">
225
+ <PropertyGroup>
226
+ <TargetFramework>netcoreapp2.1</TargetFramework>
227
+ </PropertyGroup>
228
+ <ItemGroup>
229
+ <PackageReference Include="Microsoft.Extensions.Primitives" Version="2.2.0" />
230
+ <PackageReference Include="Microsoft.Extensions.Options" Version="2.2.0" />
231
+ <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.2.0" />
232
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
233
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
234
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
235
+ <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.0" />
236
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
237
+ <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
238
+ <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
239
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" />
240
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.0" />
241
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="2.2.0" />
242
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="2.2.0" />
243
+ <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
244
+ <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" />
245
+ <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
246
+ </ItemGroup>
247
+ </Project>
248
+ """)
249
+ }, // expected contents
250
+ "Microsoft.EntityFrameworkCore.SqlServer", "2.1.0", "2.2.0", false // isTransitive
251
+ };
252
+
190
253
  // PackageReference with Version as child element
191
254
  yield return new object[]
192
255
  {
@@ -72,7 +72,9 @@ module Dependabot
72
72
  project_files += fsproj_file
73
73
  project_files += sln_project_files
74
74
  project_files += proj_files
75
- project_files += project_files.filter_map { |f| directory_packages_props_file_from_project_file(f) }
75
+ project_files += project_files.filter_map do |f|
76
+ named_file_up_tree_from_project_file(f, "Directory.Packages.props")
77
+ end
76
78
  project_files
77
79
  end
78
80
  rescue Octokit::NotFound, Gitlab::Error::NotFound
@@ -191,28 +193,6 @@ module Dependabot
191
193
  @proj_files ||= find_and_fetch_with_suffix(".proj")
192
194
  end
193
195
 
194
- def directory_packages_props_file_from_project_file(project_file)
195
- # walk up the tree from each project file stopping at the first `Directory.Packages.props` file found
196
- # https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#central-package-management-rules
197
-
198
- found_directory_packages_props_file = nil
199
- directory_path = Pathname.new(directory)
200
- full_project_dir = Pathname.new(project_file.directory).join(project_file.name).dirname
201
- full_project_dir.ascend.each do |base|
202
- break if found_directory_packages_props_file
203
-
204
- candidate_file_path = Pathname.new(base).join("Directory.Packages.props").cleanpath.to_path
205
- candidate_directory = Pathname.new(File.dirname(candidate_file_path))
206
- relative_candidate_directory = candidate_directory.relative_path_from(directory_path)
207
- candidate_file = repo_contents(dir: relative_candidate_directory).find do |f|
208
- f.name.casecmp?("Directory.Packages.props")
209
- end
210
- found_directory_packages_props_file = fetch_file_from_host(candidate_file.name) if candidate_file
211
- end
212
-
213
- found_directory_packages_props_file
214
- end
215
-
216
196
  def find_and_fetch_with_suffix(suffix)
217
197
  repo_contents.select { |f| f.name.end_with?(suffix) }.map { |f| fetch_file_from_host(f.name) }
218
198
  end
@@ -293,47 +293,8 @@ module Dependabot
293
293
  end
294
294
 
295
295
  def dependency_url_has_matching_result?(dependency_name, dependency_url)
296
- repository_type = dependency_url.fetch(:repository_type)
297
- if repository_type == "v3"
298
- dependency_url_has_matching_result_v3?(dependency_name, dependency_url)
299
- elsif repository_type == "v2"
300
- dependency_url_has_matching_result_v2?(dependency_name, dependency_url)
301
- else
302
- raise "Unknown repository type: #{repository_type}"
303
- end
304
- end
305
-
306
- def dependency_url_has_matching_result_v3?(dependency_name, dependency_url)
307
- versions = NugetClient.get_package_versions_v3(dependency_name, dependency_url)
308
-
309
- versions != nil
310
- end
311
-
312
- def dependency_url_has_matching_result_v2?(dependency_name, dependency_url)
313
- url = dependency_url.fetch(:versions_url)
314
- auth_header = dependency_url.fetch(:auth_header)
315
- response = execute_search_for_dependency_url(url, auth_header)
316
- return false unless response.status == 200
317
-
318
- doc = Nokogiri::XML(response.body)
319
- doc.remove_namespaces!
320
- id_nodes = doc.xpath("/feed/entry/properties/Id")
321
- found_matching_result = id_nodes.any? do |id_node|
322
- return false unless id_node.text
323
-
324
- id_node.text.casecmp?(dependency_name)
325
- end
326
- found_matching_result
327
- end
328
-
329
- def execute_search_for_dependency_url(url, auth_header)
330
- cache = ProjectFileParser.dependency_url_search_cache
331
- cache[url] ||= Dependabot::RegistryClient.get(
332
- url: url,
333
- headers: auth_header
334
- )
335
-
336
- cache[url]
296
+ versions = NugetClient.get_package_versions(dependency_name, dependency_url)
297
+ versions&.any?
337
298
  end
338
299
 
339
300
  def dependency_name(dependency_node, project_file)
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "nokogiri"
@@ -85,7 +85,7 @@ module Dependabot
85
85
 
86
86
  def packages_config_files
87
87
  dependency_files.select do |f|
88
- f.name.split("/").last.casecmp("packages.config").zero?
88
+ f.name.split("/").last&.casecmp("packages.config")&.zero?
89
89
  end
90
90
  end
91
91
 
@@ -103,11 +103,11 @@ module Dependabot
103
103
  end
104
104
 
105
105
  def global_json
106
- dependency_files.find { |f| f.name.casecmp("global.json").zero? }
106
+ dependency_files.find { |f| f.name.casecmp("global.json")&.zero? }
107
107
  end
108
108
 
109
109
  def dotnet_tools_json
110
- dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json").zero? }
110
+ dependency_files.find { |f| f.name.casecmp(".config/dotnet-tools.json")&.zero? }
111
111
  end
112
112
 
113
113
  def check_required_files
@@ -7,7 +7,18 @@ require "dependabot/nuget/update_checker/repository_finder"
7
7
  module Dependabot
8
8
  module Nuget
9
9
  class NugetClient
10
- def self.get_package_versions_v3(dependency_name, repository_details)
10
+ def self.get_package_versions(dependency_name, repository_details)
11
+ repository_type = repository_details.fetch(:repository_type)
12
+ if repository_type == "v3"
13
+ get_package_versions_v3(dependency_name, repository_details)
14
+ elsif repository_type == "v2"
15
+ get_package_versions_v2(dependency_name, repository_details)
16
+ else
17
+ raise "Unknown repository type: #{repository_type}"
18
+ end
19
+ end
20
+
21
+ private_class_method def self.get_package_versions_v3(dependency_name, repository_details)
11
22
  # Use the registration URL if possible because it is fast and correct
12
23
  if repository_details[:registration_url]
13
24
  get_versions_from_registration_v3(repository_details)
@@ -20,14 +31,32 @@ module Dependabot
20
31
  end
21
32
  end
22
33
 
34
+ private_class_method def self.get_package_versions_v2(dependency_name, repository_details)
35
+ doc = execute_xml_nuget_request(repository_details.fetch(:versions_url), repository_details)
36
+ return unless doc
37
+
38
+ id_nodes = doc.xpath("/feed/entry/properties/Id")
39
+ matching_versions = Set.new
40
+ id_nodes.each do |id_node|
41
+ return nil unless id_node.text
42
+
43
+ next unless id_node.text.casecmp?(dependency_name)
44
+
45
+ version_node = id_node.parent.xpath("Version")
46
+ matching_versions << version_node.text if version_node && version_node.text
47
+ end
48
+
49
+ matching_versions
50
+ end
51
+
23
52
  private_class_method def self.get_versions_from_versions_url_v3(repository_details)
24
- body = execute_search_for_dependency_url(repository_details[:versions_url], repository_details)
53
+ body = execute_json_nuget_request(repository_details[:versions_url], repository_details)
25
54
  body&.fetch("versions")
26
55
  end
27
56
 
28
57
  private_class_method def self.get_versions_from_registration_v3(repository_details)
29
58
  url = repository_details[:registration_url]
30
- body = execute_search_for_dependency_url(url, repository_details)
59
+ body = execute_json_nuget_request(url, repository_details)
31
60
 
32
61
  return unless body
33
62
 
@@ -47,7 +76,7 @@ module Dependabot
47
76
  else
48
77
  # paged entries
49
78
  page_url = page["@id"]
50
- page_body = execute_search_for_dependency_url(page_url, repository_details)
79
+ page_body = execute_json_nuget_request(page_url, repository_details)
51
80
  items = page_body.fetch("items")
52
81
  items.each do |item|
53
82
  catalog_entry = item.fetch("catalogEntry")
@@ -61,7 +90,7 @@ module Dependabot
61
90
 
62
91
  private_class_method def self.get_versions_from_search_url_v3(repository_details, dependency_name)
63
92
  search_url = repository_details[:search_url]
64
- body = execute_search_for_dependency_url(search_url, repository_details)
93
+ body = execute_json_nuget_request(search_url, repository_details)
65
94
 
66
95
  body&.fetch("data")
67
96
  &.find { |d| d.fetch("id").casecmp(dependency_name.downcase).zero? }
@@ -69,21 +98,55 @@ module Dependabot
69
98
  &.map { |d| d.fetch("version") }
70
99
  end
71
100
 
72
- private_class_method def self.execute_search_for_dependency_url(url, repository_details)
73
- cache = CacheManager.cache("dependency_url_search_cache")
74
- cache[url] ||= Dependabot::RegistryClient.get(
101
+ private_class_method def self.execute_xml_nuget_request(url, repository_details)
102
+ response = execute_nuget_request_internal(
75
103
  url: url,
76
- headers: repository_details[:auth_header]
104
+ auth_header: repository_details[:auth_header],
105
+ repository_url: repository_details[:repository_url]
77
106
  )
107
+ return unless response.status == 200
78
108
 
79
- response = cache[url]
109
+ doc = Nokogiri::XML(response.body)
110
+ doc.remove_namespaces!
111
+ doc
112
+ end
80
113
 
114
+ private_class_method def self.execute_json_nuget_request(url, repository_details)
115
+ response = execute_nuget_request_internal(
116
+ url: url,
117
+ auth_header: repository_details[:auth_header],
118
+ repository_url: repository_details[:repository_url]
119
+ )
81
120
  return unless response.status == 200
82
121
 
83
122
  body = remove_wrapping_zero_width_chars(response.body)
84
123
  JSON.parse(body)
124
+ end
125
+
126
+ private_class_method def self.execute_nuget_request_internal(
127
+ url: String,
128
+ auth_header: String,
129
+ repository_url: String
130
+ )
131
+ cache = CacheManager.cache("dependency_url_search_cache")
132
+ if cache[url].nil?
133
+ response = Dependabot::RegistryClient.get(
134
+ url: url,
135
+ headers: auth_header
136
+ )
137
+
138
+ if [401, 402, 403].include?(response.status)
139
+ raise Dependabot::PrivateSourceAuthenticationFailure, repository_url
140
+ end
141
+
142
+ cache[url] = response if !CacheManager.caching_disabled? && response.status == 200
143
+ else
144
+ response = cache[url]
145
+ end
146
+
147
+ response
85
148
  rescue Excon::Error::Timeout, Excon::Error::Socket
86
- repo_url = repository_details[:repository_url]
149
+ repo_url = repository_url
87
150
  raise if repo_url == Dependabot::Nuget::UpdateChecker::RepositoryFinder::DEFAULT_REPOSITORY_URL
88
151
 
89
152
  raise PrivateSourceTimedOut, repo_url
@@ -235,7 +235,7 @@ module Dependabot
235
235
  dependency_urls
236
236
  .select { |details| details.fetch(:repository_type) == "v3" }
237
237
  .filter_map do |url_details|
238
- versions = versions_for_v3_repository(url_details)
238
+ versions = NugetClient.get_package_versions(dependency.name, url_details)
239
239
  next unless versions
240
240
 
241
241
  { "versions" => versions, "listing_details" => url_details }
@@ -294,10 +294,6 @@ module Dependabot
294
294
  nil
295
295
  end
296
296
 
297
- def versions_for_v3_repository(repository_details)
298
- NugetClient.get_package_versions_v3(dependency.name, repository_details)
299
- end
300
-
301
297
  def dependency_urls
302
298
  @dependency_urls ||=
303
299
  RepositoryFinder.new(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-nuget
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.242.0
4
+ version: 0.242.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-22 00:00:00.000000000 Z
11
+ date: 2024-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.242.0
19
+ version: 0.242.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.242.0
26
+ version: 0.242.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubyzip
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -369,7 +369,7 @@ licenses:
369
369
  - Nonstandard
370
370
  metadata:
371
371
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
372
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.242.0
372
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.242.1
373
373
  post_install_message:
374
374
  rdoc_options: []
375
375
  require_paths: