dependabot-nuget 0.265.0 → 0.267.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +6 -6
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +173 -0
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalysisResult.cs +1 -1
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +92 -79
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +21 -8
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +36 -9
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/Requirement.cs +88 -45
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +33 -16
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +44 -25
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +1 -1
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +9 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +2 -2
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/MissingFileException.cs +11 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NativeResult.cs +8 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +45 -42
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +19 -1
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +2 -1
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationResult.cs +5 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +70 -22
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +29 -1
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +6 -2
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +450 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/CompatibilityCheckerTests.cs +23 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/RequirementTests.cs +1 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +2 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +148 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -1
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +17 -22
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +81 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +27 -7
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +32 -0
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +447 -2
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +88 -0
  35. data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -0
  36. data/lib/dependabot/nuget/file_fetcher.rb +30 -11
  37. data/lib/dependabot/nuget/file_updater.rb +2 -0
  38. data/lib/dependabot/nuget/metadata_finder.rb +160 -2
  39. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +3 -0
  40. data/lib/dependabot/nuget/native_helpers.rb +36 -3
  41. data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +1 -0
  42. data/lib/dependabot/nuget/nuget_config_credential_helpers.rb +3 -0
  43. metadata +12 -7
@@ -4,7 +4,7 @@ using NuGetUpdater.Core.Discover;
4
4
 
5
5
  namespace NuGetUpdater.Core.Test.Discover;
6
6
 
7
- public record ExpectedWorkspaceDiscoveryResult
7
+ public record ExpectedWorkspaceDiscoveryResult : NativeResult
8
8
  {
9
9
  public required string Path { get; init; }
10
10
  public bool IsSuccess { get; init; } = true;
@@ -1,3 +1,4 @@
1
+ using System.Collections.Immutable;
1
2
  using System.IO.Compression;
2
3
  using System.Security.Cryptography;
3
4
  using System.Text;
@@ -95,7 +96,7 @@ namespace NuGetUpdater.Core.Test
95
96
  /// Creates a mock NuGet package with a single assembly in the appropriate `lib/` directory. The assembly will
96
97
  /// contain the appropriate `AssemblyVersion` attribute and nothing else.
97
98
  /// </summary>
98
- public static MockNuGetPackage CreatePackageWithAssembly(string id, string version, string targetFramework, string assemblyVersion, (string? TargetFramework, (string Id, string Version)[] Packages)[]? dependencyGroups = null)
99
+ public static MockNuGetPackage CreatePackageWithAssembly(string id, string version, string targetFramework, string assemblyVersion, ImmutableArray<byte>? assemblyPublicKey = null, (string? TargetFramework, (string Id, string Version)[] Packages)[]? dependencyGroups = null)
99
100
  {
100
101
  return new(
101
102
  id,
@@ -104,7 +105,7 @@ namespace NuGetUpdater.Core.Test
104
105
  DependencyGroups: dependencyGroups,
105
106
  Files:
106
107
  [
107
- ($"lib/{targetFramework}/{id}.dll", CreateAssembly(id, assemblyVersion))
108
+ ($"lib/{targetFramework}/{id}.dll", CreateAssembly(id, assemblyVersion, assemblyPublicKey))
108
109
  ]
109
110
  );
110
111
  }
@@ -130,19 +131,14 @@ namespace NuGetUpdater.Core.Test
130
131
  );
131
132
  }
132
133
 
133
- public static MockNuGetPackage CreateDotNetToolPackage(string id, string version, string targetFramework)
134
+ public static MockNuGetPackage CreateDotNetToolPackage(string id, string version, string targetFramework, XElement[]? additionalMetadata = null)
134
135
  {
136
+ var packageMetadata = new XElement("packageTypes", new XElement("packageType", new XAttribute("name", "DotnetTool")));
137
+ var allMetadata = new[] { packageMetadata }.Concat(additionalMetadata ?? []).ToArray();
135
138
  return new(
136
139
  id,
137
140
  version,
138
- AdditionalMetadata:
139
- [
140
- new XElement("packageTypes",
141
- new XElement("packageType",
142
- new XAttribute("name", "DotnetTool")
143
- )
144
- )
145
- ],
141
+ AdditionalMetadata: allMetadata,
146
142
  Files:
147
143
  [
148
144
  ($"tools/{targetFramework}/any/DotnetToolSettings.xml", Encoding.UTF8.GetBytes($"""
@@ -157,8 +153,10 @@ namespace NuGetUpdater.Core.Test
157
153
  );
158
154
  }
159
155
 
160
- public static MockNuGetPackage CreateMSBuildSdkPackage(string id, string version, string? sdkPropsContent = null, string? sdkTargetsContent = null)
156
+ public static MockNuGetPackage CreateMSBuildSdkPackage(string id, string version, string? sdkPropsContent = null, string? sdkTargetsContent = null, XElement[]? additionalMetadata = null)
161
157
  {
158
+ var packageMetadata = new XElement("packageTypes", new XElement("packageType", new XAttribute("name", "MSBuildSdk")));
159
+ var allMetadata = new[] { packageMetadata }.Concat(additionalMetadata ?? []).ToArray();
162
160
  sdkPropsContent ??= """
163
161
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
164
162
  </Project>
@@ -170,14 +168,7 @@ namespace NuGetUpdater.Core.Test
170
168
  return new(
171
169
  id,
172
170
  version,
173
- AdditionalMetadata:
174
- [
175
- new XElement("packageTypes",
176
- new XElement("packageType",
177
- new XAttribute("name", "MSBuildSdk")
178
- )
179
- )
180
- ],
171
+ AdditionalMetadata: additionalMetadata,
181
172
  Files:
182
173
  [
183
174
  ("Sdk/Sdk.props", Encoding.UTF8.GetBytes(sdkPropsContent)),
@@ -245,7 +236,7 @@ namespace NuGetUpdater.Core.Test
245
236
  );
246
237
  }
247
238
 
248
- private Stream GetZipStream()
239
+ public Stream GetZipStream()
249
240
  {
250
241
  if (_stream is null)
251
242
  {
@@ -271,9 +262,13 @@ namespace NuGetUpdater.Core.Test
271
262
  return _stream;
272
263
  }
273
264
 
274
- private static byte[] CreateAssembly(string assemblyName, string assemblyVersion)
265
+ private static byte[] CreateAssembly(string assemblyName, string assemblyVersion, ImmutableArray<byte>? assemblyPublicKey = null)
275
266
  {
276
267
  CSharpCompilationOptions compilationOptions = new(OutputKind.DynamicallyLinkedLibrary);
268
+ if (assemblyPublicKey is not null)
269
+ {
270
+ compilationOptions = compilationOptions.WithCryptoPublicKey(assemblyPublicKey.Value);
271
+ }
277
272
  CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, options: compilationOptions)
278
273
  .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
279
274
  .AddSyntaxTrees(CSharpSyntaxTree.ParseText($"[assembly: System.Reflection.AssemblyVersionAttribute(\"{assemblyVersion}\")]"));
@@ -0,0 +1,81 @@
1
+ using System.Net;
2
+ using System.Net.Sockets;
3
+ using System.Text;
4
+
5
+ namespace NuGetUpdater.Core.Test
6
+ {
7
+ public class TestHttpServer : IDisposable
8
+ {
9
+ private readonly Func<string, (int, byte[])> _requestHandler;
10
+ private readonly HttpListener _listener;
11
+ private bool _runServer = true;
12
+
13
+ public string BaseUrl { get; }
14
+
15
+ private TestHttpServer(string baseurl, Func<string, (int, byte[])> requestHandler)
16
+ {
17
+ BaseUrl = baseurl;
18
+ _requestHandler = requestHandler;
19
+ _listener = new HttpListener();
20
+ _listener.Prefixes.Add(baseurl);
21
+ }
22
+
23
+ private void Start()
24
+ {
25
+ _listener.Start();
26
+ Task.Factory.StartNew(HandleResponses);
27
+ }
28
+
29
+ public void Dispose()
30
+ {
31
+ _runServer = false;
32
+ _listener.Stop();
33
+ }
34
+
35
+ private async Task HandleResponses()
36
+ {
37
+ while (_runServer)
38
+ {
39
+ var context = await _listener.GetContextAsync();
40
+ var (statusCode, response) = _requestHandler(context.Request.Url!.AbsoluteUri);
41
+ context.Response.StatusCode = statusCode;
42
+ await context.Response.OutputStream.WriteAsync(response);
43
+ context.Response.Close();
44
+ }
45
+ }
46
+
47
+ private static readonly object PortGate = new();
48
+
49
+ public static TestHttpServer CreateTestServer(Func<string, (int, byte[])> requestHandler)
50
+ {
51
+ // static lock to ensure the port is not recycled after `FindFreePort()` and before we can start the real server
52
+ lock (PortGate)
53
+ {
54
+ var port = FindFreePort();
55
+ var baseUrl = $"http://localhost:{port}/";
56
+ var server = new TestHttpServer(baseUrl, requestHandler);
57
+ server.Start();
58
+ return server;
59
+ }
60
+ }
61
+
62
+ public static TestHttpServer CreateTestStringServer(Func<string, (int, string)> requestHandler)
63
+ {
64
+ Func<string, (int, byte[])> bytesRequestHandler = url =>
65
+ {
66
+ var (statusCode, response) = requestHandler(url);
67
+ return (statusCode, Encoding.UTF8.GetBytes(response));
68
+ };
69
+ return CreateTestServer(bytesRequestHandler);
70
+ }
71
+
72
+ private static int FindFreePort()
73
+ {
74
+ var tcpListener = new TcpListener(IPAddress.Loopback, 0);
75
+ tcpListener.Start();
76
+ var port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
77
+ tcpListener.Stop();
78
+ return port;
79
+ }
80
+ }
81
+ }
@@ -1,3 +1,7 @@
1
+ using System.Text.Json;
2
+
3
+ using NuGetUpdater.Core.Updater;
4
+
1
5
  using Xunit;
2
6
 
3
7
  namespace NuGetUpdater.Core.Test.Update;
@@ -88,7 +92,8 @@ public abstract class UpdateWorkerTestBase : TestBase
88
92
  TestFile[]? additionalFiles = null,
89
93
  TestFile[]? additionalFilesExpected = null,
90
94
  MockNuGetPackage[]? packages = null,
91
- string projectFilePath = "test-project.csproj")
95
+ string projectFilePath = "test-project.csproj",
96
+ UpdateOperationResult? expectedResult = null)
92
97
  => TestUpdateForProject(
93
98
  dependencyName,
94
99
  oldVersion,
@@ -98,7 +103,8 @@ public abstract class UpdateWorkerTestBase : TestBase
98
103
  isTransitive,
99
104
  additionalFiles,
100
105
  additionalFilesExpected,
101
- packages);
106
+ packages,
107
+ expectedResult);
102
108
 
103
109
  protected static async Task TestUpdateForProject(
104
110
  string dependencyName,
@@ -109,7 +115,8 @@ public abstract class UpdateWorkerTestBase : TestBase
109
115
  bool isTransitive = false,
110
116
  TestFile[]? additionalFiles = null,
111
117
  TestFile[]? additionalFilesExpected = null,
112
- MockNuGetPackage[]? packages = null)
118
+ MockNuGetPackage[]? packages = null,
119
+ UpdateOperationResult? expectedResult = null)
113
120
  {
114
121
  additionalFiles ??= [];
115
122
  additionalFilesExpected ??= [];
@@ -130,16 +137,29 @@ public abstract class UpdateWorkerTestBase : TestBase
130
137
  // run update
131
138
  var worker = new UpdaterWorker(new Logger(verbose: true));
132
139
  var projectPath = placeFilesInSrc ? $"src/{projectFilePath}" : projectFilePath;
133
- await worker.RunAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
140
+ var updateResultFile = Path.Combine(temporaryDirectory, "update-result.json");
141
+ await worker.RunAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive, updateResultFile);
142
+ var actualResultContents = await File.ReadAllTextAsync(updateResultFile);
143
+ var actualResult = JsonSerializer.Deserialize<UpdateOperationResult>(actualResultContents, UpdaterWorker.SerializerOptions);
144
+ if (expectedResult is { })
145
+ {
146
+ ValidateUpdateOperationResult(expectedResult, actualResult!);
147
+ }
134
148
  });
135
149
 
136
- var expectedResult = additionalFilesExpected.Prepend((projectFilePath, expectedProjectContents)).ToArray();
150
+ var expectedResultFiles = additionalFilesExpected.Prepend((projectFilePath, expectedProjectContents)).ToArray();
137
151
  if (placeFilesInSrc)
138
152
  {
139
- expectedResult = expectedResult.Select(er => ($"src/{er.Item1}", er.Item2)).ToArray();
153
+ expectedResultFiles = expectedResultFiles.Select(er => ($"src/{er.Item1}", er.Item2)).ToArray();
140
154
  }
141
155
 
142
- AssertContainsFiles(expectedResult, actualResult);
156
+ AssertContainsFiles(expectedResultFiles, actualResult);
157
+ }
158
+
159
+ protected static void ValidateUpdateOperationResult(UpdateOperationResult expectedResult, UpdateOperationResult actualResult)
160
+ {
161
+ Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
162
+ Assert.Equal(expectedResult.ErrorDetails, actualResult.ErrorDetails);
143
163
  }
144
164
 
145
165
  protected static Task TestNoChangeforSolution(
@@ -1,3 +1,7 @@
1
+ using System.Text.Json;
2
+
3
+ using NuGetUpdater.Core.Updater;
4
+
1
5
  using Xunit;
2
6
 
3
7
  namespace NuGetUpdater.Core.Test.Update;
@@ -6,6 +10,34 @@ public partial class UpdateWorkerTests
6
10
  {
7
11
  public class Mixed : UpdateWorkerTestBase
8
12
  {
13
+ [Fact]
14
+ public async Task ResultFileHasCorrectShapeForAuthenticationFailure()
15
+ {
16
+ using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync([]);
17
+ var result = new UpdateOperationResult()
18
+ {
19
+ ErrorType = ErrorType.AuthenticationFailure,
20
+ ErrorDetails = "<some package feed>",
21
+ };
22
+ var resultFilePath = Path.Combine(temporaryDirectory.DirectoryPath, "update-result.json");
23
+ await UpdaterWorker.WriteResultFile(result, resultFilePath, new Logger(false));
24
+ var resultContent = await File.ReadAllTextAsync(resultFilePath);
25
+
26
+ // raw result file should look like this:
27
+ // {
28
+ // ...
29
+ // "ErrorType": "AuthenticationFailure",
30
+ // "ErrorDetails": "<some package feed>",
31
+ // ...
32
+ // }
33
+ var jsonDocument = JsonDocument.Parse(resultContent);
34
+ var errorType = jsonDocument.RootElement.GetProperty("ErrorType");
35
+ var errorDetails = jsonDocument.RootElement.GetProperty("ErrorDetails");
36
+
37
+ Assert.Equal("AuthenticationFailure", errorType.GetString());
38
+ Assert.Equal("<some package feed>", errorDetails.GetString());
39
+ }
40
+
9
41
  [Fact]
10
42
  public async Task ForPackagesProject_UpdatePackageReference_InBuildProps()
11
43
  {