dependabot-nuget 0.265.0 → 0.267.0

Sign up to get free protection for your applications and to get access to all the features.
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
  {