dependabot-nuget 0.292.0 → 0.293.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/.gitignore +1 -0
  3. data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -0
  4. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Correlator.cs +197 -0
  5. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/DotNetPackageCorrelation.csproj +12 -0
  6. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageMapper.cs +68 -0
  7. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageSet.cs +11 -0
  8. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/Release.cs +25 -0
  9. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/ReleasesFile.cs +9 -0
  10. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/RuntimePackages.cs +11 -0
  11. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/Sdk.cs +13 -0
  12. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/SemVerComparer.cs +16 -0
  13. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/SemVersionConverter.cs +42 -0
  14. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/DotNetPackageCorrelation.Cli.csproj +16 -0
  15. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +32 -0
  16. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/CorrelatorTests.cs +99 -0
  17. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/DotNetPackageCorrelation.Test.csproj +18 -0
  18. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/EndToEndTests.cs +30 -0
  19. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/RuntimePackagesTests.cs +206 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +6 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +8 -7
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +4 -4
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +17 -5
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +7 -1
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +46 -6
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +8 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +8 -17
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +4 -4
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/Extensions.cs +1 -1
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +2 -1
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +2 -2
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +7 -20
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +3 -3
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +99 -2
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EnsureDotNetPackageCorrelation.targets +25 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +9 -22
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/PackagesConfigBuildFile.cs +5 -1
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/MissingFileException.cs +2 -1
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NativeResult.cs +3 -3
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +3 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotFound.cs +7 -3
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotParseable.cs +15 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +24 -0
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +6 -21
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/UnparseableFileException.cs +12 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +21 -0
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +6 -30
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DotNetPackageCorrelationManager.cs +46 -0
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +51 -27
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -1
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +15 -4
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +15 -9
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +20 -12
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +108 -0
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +16 -12
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -1
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +15 -28
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +5 -4
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +9 -1
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +24 -0
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/ExpectedUpdateOperationResult.cs +1 -1
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +11 -15
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +1 -1
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +14 -8
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +148 -3
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +12 -14
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.sln +18 -1
  68. data/lib/dependabot/nuget/native_helpers.rb +41 -16
  69. metadata +25 -6
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +0 -12
@@ -388,6 +388,17 @@ namespace NuGetUpdater.Core.Test
388
388
  return WellKnownPackages[key];
389
389
  }
390
390
 
391
+ public static MockNuGetPackage GetMicrosoftNETCoreAppRefPackage(int majorRuntimeVersion)
392
+ {
393
+ return WellKnownReferencePackage("Microsoft.NETCore.App", $"net{majorRuntimeVersion}.0",
394
+ [
395
+ ("data/FrameworkList.xml", Encoding.UTF8.GetBytes($"""
396
+ <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="{majorRuntimeVersion}.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
397
+ </FileList>
398
+ """))
399
+ ]);
400
+ }
401
+
391
402
  public static MockNuGetPackage WellKnownHostPackage(string packageName, string targetFramework, (string Path, byte[] Content)[]? files = null)
392
403
  {
393
404
  string key = $"{packageName}/{targetFramework}";
@@ -437,34 +448,10 @@ namespace NuGetUpdater.Core.Test
437
448
  WellKnownReferencePackage("Microsoft.AspNetCore.App", "net7.0"),
438
449
  WellKnownReferencePackage("Microsoft.AspNetCore.App", "net8.0"),
439
450
  WellKnownReferencePackage("Microsoft.AspNetCore.App", "net9.0"),
440
- WellKnownReferencePackage("Microsoft.NETCore.App", "net6.0",
441
- [
442
- ("data/FrameworkList.xml", Encoding.UTF8.GetBytes("""
443
- <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="6.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
444
- </FileList>
445
- """))
446
- ]),
447
- WellKnownReferencePackage("Microsoft.NETCore.App", "net7.0",
448
- [
449
- ("data/FrameworkList.xml", Encoding.UTF8.GetBytes("""
450
- <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="7.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
451
- </FileList>
452
- """))
453
- ]),
454
- WellKnownReferencePackage("Microsoft.NETCore.App", "net8.0",
455
- [
456
- ("data/FrameworkList.xml", Encoding.UTF8.GetBytes("""
457
- <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="8.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
458
- </FileList>
459
- """))
460
- ]),
461
- WellKnownReferencePackage("Microsoft.NETCore.App", "net9.0",
462
- [
463
- ("data/FrameworkList.xml", Encoding.UTF8.GetBytes("""
464
- <FileList TargetFrameworkIdentifier=".NETCoreApp" TargetFrameworkVersion="9.0" FrameworkName="Microsoft.NETCore.App" Name=".NET Runtime">
465
- </FileList>
466
- """))
467
- ]),
451
+ GetMicrosoftNETCoreAppRefPackage(6),
452
+ GetMicrosoftNETCoreAppRefPackage(7),
453
+ GetMicrosoftNETCoreAppRefPackage(8),
454
+ GetMicrosoftNETCoreAppRefPackage(9),
468
455
  WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net6.0"),
469
456
  WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net7.0"),
470
457
  WellKnownReferencePackage("Microsoft.WindowsDesktop.App", "net8.0"),
@@ -1729,11 +1729,12 @@ public class RunWorkerTests
1729
1729
  experimentsManager ??= new ExperimentsManager();
1730
1730
  var testApiHandler = new TestApiHandler();
1731
1731
  var logger = new TestLogger();
1732
- discoveryWorker ??= new DiscoveryWorker(experimentsManager, logger);
1733
- analyzeWorker ??= new AnalyzeWorker(experimentsManager, logger);
1734
- updaterWorker ??= new UpdaterWorker(experimentsManager, logger);
1732
+ var jobId = "TEST-JOB-ID";
1733
+ discoveryWorker ??= new DiscoveryWorker(jobId, experimentsManager, logger);
1734
+ analyzeWorker ??= new AnalyzeWorker(jobId, experimentsManager, logger);
1735
+ updaterWorker ??= new UpdaterWorker(jobId, experimentsManager, logger);
1735
1736
 
1736
- var worker = new RunWorker("TEST-JOB-ID", testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);
1737
+ var worker = new RunWorker(jobId, testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);
1737
1738
  var repoContentsPathDirectoryInfo = new DirectoryInfo(tempDirectory.DirectoryPath);
1738
1739
  var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA");
1739
1740
  var actualApiMessages = testApiHandler.ReceivedMessages.ToArray();
@@ -523,12 +523,20 @@ public class SerializationTests
523
523
 
524
524
  yield return
525
525
  [
526
- new DependencyFileNotFound("some message", "/some/file"),
526
+ new DependencyFileNotFound("/some/file", "some message"),
527
527
  """
528
528
  {"data":{"error-type":"dependency_file_not_found","error-details":{"message":"some message","file-path":"/some/file"}}}
529
529
  """
530
530
  ];
531
531
 
532
+ yield return
533
+ [
534
+ new DependencyFileNotParseable("/some/file", "some message"),
535
+ """
536
+ {"data":{"error-type":"dependency_file_not_parseable","error-details":{"message":"some message","file-path":"/some/file"}}}
537
+ """
538
+ ];
539
+
532
540
  yield return
533
541
  [
534
542
  new JobRepoNotFound("some message"),
@@ -1,3 +1,10 @@
1
+ using System.Text.Json;
2
+
3
+ using NuGetUpdater.Core.Run.ApiModel;
4
+ using NuGetUpdater.Core.Run;
5
+
6
+ using Xunit;
7
+
1
8
  namespace NuGetUpdater.Core.Test
2
9
  {
3
10
  public abstract class TestBase
@@ -6,5 +13,22 @@ namespace NuGetUpdater.Core.Test
6
13
  {
7
14
  MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, Environment.CurrentDirectory);
8
15
  }
16
+
17
+ protected static void ValidateError(JobErrorBase expected, JobErrorBase? actual)
18
+ {
19
+ var expectedErrorString = JsonSerializer.Serialize(expected, RunWorker.SerializerOptions);
20
+ var actualErrorString = actual is null
21
+ ? null
22
+ : JsonSerializer.Serialize(actual, RunWorker.SerializerOptions);
23
+ Assert.Equal(expectedErrorString, actualErrorString);
24
+ }
25
+
26
+ protected static void ValidateErrorRegex(string expectedErrorRegex, JobErrorBase? actual)
27
+ {
28
+ var actualErrorString = actual is null
29
+ ? null
30
+ : JsonSerializer.Serialize(actual, RunWorker.SerializerOptions);
31
+ Assert.Matches(expectedErrorRegex, actualErrorString);
32
+ }
9
33
  }
10
34
  }
@@ -4,5 +4,5 @@ namespace NuGetUpdater.Core.Test.Updater;
4
4
 
5
5
  public record ExpectedUpdateOperationResult : UpdateOperationResult
6
6
  {
7
- public string? ErrorDetailsRegex { get; init; } = null;
7
+ public string? ErrorRegex { get; init; } = null;
8
8
  }
@@ -152,17 +152,10 @@ public abstract class UpdateWorkerTestBase : TestBase
152
152
 
153
153
  // run update
154
154
  experimentsManager ??= new ExperimentsManager();
155
- var worker = new UpdaterWorker(experimentsManager, new TestLogger());
155
+ var worker = new UpdaterWorker("TEST-JOB-ID", experimentsManager, new TestLogger());
156
156
  var projectPath = placeFilesInSrc ? $"src/{projectFilePath}" : projectFilePath;
157
157
  var actualResult = await worker.RunWithErrorHandlingAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
158
- if (expectedResult is { })
159
- {
160
- ValidateUpdateOperationResult(expectedResult, actualResult!);
161
- }
162
- else if ((actualResult.ErrorType ?? ErrorType.None) != ErrorType.None)
163
- {
164
- throw new Exception($"Result indicates failure: ErrorType={actualResult.ErrorType}, ErrorDetails={actualResult.ErrorDetails}");
165
- }
158
+ ValidateUpdateOperationResult(expectedResult, actualResult!);
166
159
 
167
160
  if (additionalChecks is not null)
168
161
  {
@@ -185,16 +178,19 @@ public abstract class UpdateWorkerTestBase : TestBase
185
178
  AssertContainsFiles(expectedResultFiles, actualResult);
186
179
  }
187
180
 
188
- protected static void ValidateUpdateOperationResult(ExpectedUpdateOperationResult expectedResult, UpdateOperationResult actualResult)
181
+ protected static void ValidateUpdateOperationResult(ExpectedUpdateOperationResult? expectedResult, UpdateOperationResult actualResult)
189
182
  {
190
- Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
191
- if (expectedResult.ErrorDetailsRegex is not null && actualResult.ErrorDetails is string errorDetails)
183
+ if (expectedResult?.Error is not null)
184
+ {
185
+ ValidateError(expectedResult.Error, actualResult.Error);
186
+ }
187
+ else if (expectedResult?.ErrorRegex is not null)
192
188
  {
193
- Assert.Matches(expectedResult.ErrorDetailsRegex, errorDetails);
189
+ ValidateErrorRegex(expectedResult.ErrorRegex, actualResult.Error);
194
190
  }
195
191
  else
196
192
  {
197
- Assert.Equivalent(expectedResult.ErrorDetails, actualResult.ErrorDetails);
193
+ Assert.Null(actualResult.Error);
198
194
  }
199
195
  }
200
196
 
@@ -274,7 +270,7 @@ public abstract class UpdateWorkerTestBase : TestBase
274
270
 
275
271
  experimentsManager ??= new ExperimentsManager();
276
272
  var slnPath = Path.Combine(temporaryDirectory, slnName);
277
- var worker = new UpdaterWorker(experimentsManager, new TestLogger());
273
+ var worker = new UpdaterWorker("TEST-JOB-ID", experimentsManager, new TestLogger());
278
274
  await worker.RunAsync(temporaryDirectory, slnPath, dependencyName, oldVersion, newVersion, isTransitive);
279
275
  });
280
276
 
@@ -366,7 +366,7 @@ public partial class UpdateWorkerTests
366
366
 
367
367
  experimentsManager ??= new ExperimentsManager();
368
368
  var projectPath = Path.Combine(temporaryDirectory, projectFileName);
369
- var worker = new UpdaterWorker(experimentsManager, new TestLogger());
369
+ var worker = new UpdaterWorker("TEST-JOB-ID", experimentsManager, new TestLogger());
370
370
  await worker.RunAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
371
371
  });
372
372
 
@@ -1,5 +1,6 @@
1
1
  using System.Text.Json;
2
2
 
3
+ using NuGetUpdater.Core.Run.ApiModel;
3
4
  using NuGetUpdater.Core.Updater;
4
5
 
5
6
  using Xunit;
@@ -16,8 +17,7 @@ public partial class UpdateWorkerTests
16
17
  using var temporaryDirectory = await TemporaryDirectory.CreateWithContentsAsync([]);
17
18
  var result = new UpdateOperationResult()
18
19
  {
19
- ErrorType = ErrorType.AuthenticationFailure,
20
- ErrorDetails = "<some package feed>",
20
+ Error = new PrivateSourceAuthenticationFailure(["<some package feed>"]),
21
21
  };
22
22
  var resultFilePath = Path.Combine(temporaryDirectory.DirectoryPath, "update-result.json");
23
23
  await UpdaterWorker.WriteResultFile(result, resultFilePath, new TestLogger());
@@ -26,16 +26,22 @@ public partial class UpdateWorkerTests
26
26
  // raw result file should look like this:
27
27
  // {
28
28
  // ...
29
- // "ErrorType": "AuthenticationFailure",
30
- // "ErrorDetails": "<some package feed>",
29
+ // "Error": {
30
+ // "error-type": "private_source_authentication_failure",
31
+ // "error-details": {
32
+ // "source": "<some package feed>"
33
+ // }
34
+ // }
31
35
  // ...
32
36
  // }
33
37
  var jsonDocument = JsonDocument.Parse(resultContent);
34
- var errorType = jsonDocument.RootElement.GetProperty("ErrorType");
35
- var errorDetails = jsonDocument.RootElement.GetProperty("ErrorDetails");
38
+ var error = jsonDocument.RootElement.GetProperty("Error");
39
+ var errorType = error.GetProperty("error-type");
40
+ var errorDetails = error.GetProperty("error-details");
41
+ var source = errorDetails.GetProperty("source");
36
42
 
37
- Assert.Equal("AuthenticationFailure", errorType.GetString());
38
- Assert.Equal("<some package feed>", errorDetails.GetString());
43
+ Assert.Equal("private_source_authentication_failure", errorType.GetString());
44
+ Assert.Equal("(<some package feed>)", source.GetString());
39
45
  }
40
46
 
41
47
  [Fact]
@@ -2,6 +2,7 @@ using System.Linq;
2
2
  using System.Text;
3
3
  using System.Text.Json;
4
4
 
5
+ using NuGetUpdater.Core.Run.ApiModel;
5
6
  using NuGetUpdater.Core.Updater;
6
7
 
7
8
  using Xunit;
@@ -571,7 +572,7 @@ public partial class UpdateWorkerTests
571
572
  //
572
573
  // do the update
573
574
  //
574
- UpdaterWorker worker = new(new ExperimentsManager(), new TestLogger());
575
+ UpdaterWorker worker = new("TEST-JOB-ID", new ExperimentsManager(), new TestLogger());
575
576
  await worker.RunAsync(tempDirectory.DirectoryPath, projectPath, "Some.Package", "1.0.0", "1.1.0", isTransitive: false);
576
577
 
577
578
  //
@@ -3482,10 +3483,154 @@ public partial class UpdateWorkerTests
3482
3483
  """,
3483
3484
  expectedResult: new()
3484
3485
  {
3485
- ErrorType = ErrorType.AuthenticationFailure,
3486
- ErrorDetails = $"({http.BaseUrl.TrimEnd('/')}/index.json)",
3486
+ Error = new PrivateSourceAuthenticationFailure([$"{http.BaseUrl.TrimEnd('/')}/index.json"]),
3487
3487
  }
3488
3488
  );
3489
3489
  }
3490
+
3491
+ [Fact]
3492
+ public async Task UpdateSdkManagedPackage_DirectDependency()
3493
+ {
3494
+ // To avoid a unit test that's tightly coupled to the installed SDK, several values are simulated,
3495
+ // including the runtime major version, the current Microsoft.NETCore.App.Ref package, and the package
3496
+ // correlation file. Doing this requires a temporary file and environment variable override.
3497
+ var runtimeMajorVersion = Environment.Version.Major;
3498
+ var netCoreAppRefPackage = MockNuGetPackage.GetMicrosoftNETCoreAppRefPackage(runtimeMajorVersion);
3499
+ using var tempDirectory = new TemporaryDirectory();
3500
+ var packageCorrelationFile = Path.Combine(tempDirectory.DirectoryPath, "dotnet-package-correlation.json");
3501
+ await File.WriteAllTextAsync(packageCorrelationFile, $$"""
3502
+ {
3503
+ "Runtimes": {
3504
+ "{{runtimeMajorVersion}}.0.0": {
3505
+ "Packages": {
3506
+ "{{netCoreAppRefPackage.Id}}": "{{netCoreAppRefPackage.Version}}",
3507
+ "System.Text.Json": "{{runtimeMajorVersion}}.0.98"
3508
+ }
3509
+ }
3510
+ }
3511
+ }
3512
+ """);
3513
+ using var tempEnvironment = new TemporaryEnvironment([("DOTNET_PACKAGE_CORRELATION_FILE_PATH", packageCorrelationFile)]);
3514
+
3515
+ // In the `packages` section below, we fake a `System.Text.Json` package with a low assembly version that
3516
+ // will always trigger the replacement so that can be detected and then the equivalent version is pulled
3517
+ // from the correlation file specified above. In the original project contents, package version `x.0.98`
3518
+ // is reported which makes the update to `x.0.99` always possible.
3519
+ await TestUpdateForProject("System.Text.Json", $"{runtimeMajorVersion}.0.98", $"{runtimeMajorVersion}.0.99",
3520
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true, InstallDotnetSdks = true },
3521
+ packages:
3522
+ [
3523
+ // this assembly version is lower than what the SDK will have
3524
+ MockNuGetPackage.CreatePackageWithAssembly("System.Text.Json", $"{runtimeMajorVersion}.0.0", $"net{runtimeMajorVersion}.0", assemblyVersion: $"{runtimeMajorVersion}.0.0.0"),
3525
+ // this assembly version is greater than what the SDK will have
3526
+ MockNuGetPackage.CreatePackageWithAssembly("System.Text.Json", $"{runtimeMajorVersion}.0.99", $"net{runtimeMajorVersion}.0", assemblyVersion: $"{runtimeMajorVersion}.99.99.99"),
3527
+ ],
3528
+ projectContents: $"""
3529
+ <Project Sdk="Microsoft.NET.Sdk">
3530
+ <PropertyGroup>
3531
+ <TargetFramework>net{runtimeMajorVersion}.0</TargetFramework>
3532
+ </PropertyGroup>
3533
+ <ItemGroup>
3534
+ <PackageReference Include="System.Text.Json" Version="{runtimeMajorVersion}.0.0" />
3535
+ </ItemGroup>
3536
+ </Project>
3537
+ """,
3538
+ additionalFiles: [
3539
+ ("global.json", $$"""
3540
+ {
3541
+ "sdk": {
3542
+ "version": "{{runtimeMajorVersion}}.0.100",
3543
+ "allowPrerelease": true,
3544
+ "rollForward": "latestMinor"
3545
+ }
3546
+ }
3547
+ """)
3548
+ ],
3549
+ expectedProjectContents: $"""
3550
+ <Project Sdk="Microsoft.NET.Sdk">
3551
+ <PropertyGroup>
3552
+ <TargetFramework>net{runtimeMajorVersion}.0</TargetFramework>
3553
+ </PropertyGroup>
3554
+ <ItemGroup>
3555
+ <PackageReference Include="System.Text.Json" Version="{runtimeMajorVersion}.0.99" />
3556
+ </ItemGroup>
3557
+ </Project>
3558
+ """
3559
+ );
3560
+ }
3561
+
3562
+ [Fact]
3563
+ public async Task UpdateSdkManagedPackage_TransitiveDependency()
3564
+ {
3565
+ // To avoid a unit test that's tightly coupled to the installed SDK, several values are simulated,
3566
+ // including the runtime major version, the current Microsoft.NETCore.App.Ref package, and the package
3567
+ // correlation file. Doing this requires a temporary file and environment variable override.
3568
+ var runtimeMajorVersion = Environment.Version.Major;
3569
+ var netCoreAppRefPackage = MockNuGetPackage.GetMicrosoftNETCoreAppRefPackage(runtimeMajorVersion);
3570
+ using var tempDirectory = new TemporaryDirectory();
3571
+ var packageCorrelationFile = Path.Combine(tempDirectory.DirectoryPath, "dotnet-package-correlation.json");
3572
+ await File.WriteAllTextAsync(packageCorrelationFile, $$"""
3573
+ {
3574
+ "Runtimes": {
3575
+ "{{runtimeMajorVersion}}.0.0": {
3576
+ "Packages": {
3577
+ "{{netCoreAppRefPackage.Id}}": "{{netCoreAppRefPackage.Version}}",
3578
+ "System.Text.Json": "{{runtimeMajorVersion}}.0.98"
3579
+ }
3580
+ }
3581
+ }
3582
+ }
3583
+ """);
3584
+ using var tempEnvironment = new TemporaryEnvironment([("DOTNET_PACKAGE_CORRELATION_FILE_PATH", packageCorrelationFile)]);
3585
+
3586
+ // In the `packages` section below, we fake a `System.Text.Json` package with a low assembly version that
3587
+ // will always trigger the replacement so that can be detected and then the equivalent version is pulled
3588
+ // from the correlation file specified above. In the original project contents, package version `x.0.98`
3589
+ // is reported which makes the update to `x.0.99` always possible.
3590
+ await TestUpdateForProject("System.Text.Json", $"{runtimeMajorVersion}.0.98", $"{runtimeMajorVersion}.0.99",
3591
+ isTransitive: true,
3592
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true, InstallDotnetSdks = true },
3593
+ packages:
3594
+ [
3595
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", $"net{runtimeMajorVersion}.0", [(null, [("System.Text.Json", $"[{runtimeMajorVersion}.0.0]")])]),
3596
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", $"net{runtimeMajorVersion}.0", [(null, [("System.Text.Json", $"[{runtimeMajorVersion}.0.99]")])]),
3597
+ // this assembly version is lower than what the SDK will have
3598
+ MockNuGetPackage.CreatePackageWithAssembly("System.Text.Json", $"{runtimeMajorVersion}.0.0", $"net{runtimeMajorVersion}.0", assemblyVersion: $"{runtimeMajorVersion}.0.0.0"),
3599
+ // this assembly version is greater than what the SDK will have
3600
+ MockNuGetPackage.CreatePackageWithAssembly("System.Text.Json", $"{runtimeMajorVersion}.0.99", $"net{runtimeMajorVersion}.0", assemblyVersion: $"{runtimeMajorVersion}.99.99.99"),
3601
+ ],
3602
+ projectContents: $"""
3603
+ <Project Sdk="Microsoft.NET.Sdk">
3604
+ <PropertyGroup>
3605
+ <TargetFramework>net{runtimeMajorVersion}.0</TargetFramework>
3606
+ </PropertyGroup>
3607
+ <ItemGroup>
3608
+ <PackageReference Include="Some.Package" Version="1.0.0" />
3609
+ </ItemGroup>
3610
+ </Project>
3611
+ """,
3612
+ additionalFiles: [
3613
+ ("global.json", $$"""
3614
+ {
3615
+ "sdk": {
3616
+ "version": "{{runtimeMajorVersion}}.0.100",
3617
+ "allowPrerelease": true,
3618
+ "rollForward": "latestMinor"
3619
+ }
3620
+ }
3621
+ """)
3622
+ ],
3623
+ expectedProjectContents: $"""
3624
+ <Project Sdk="Microsoft.NET.Sdk">
3625
+ <PropertyGroup>
3626
+ <TargetFramework>net{runtimeMajorVersion}.0</TargetFramework>
3627
+ </PropertyGroup>
3628
+ <ItemGroup>
3629
+ <PackageReference Include="Some.Package" Version="2.0.0" />
3630
+ </ItemGroup>
3631
+ </Project>
3632
+ """
3633
+ );
3634
+ }
3490
3635
  }
3491
3636
  }
@@ -4,6 +4,7 @@ using System.Text.Json;
4
4
 
5
5
  using NuGet;
6
6
 
7
+ using NuGetUpdater.Core.Run.ApiModel;
7
8
  using NuGetUpdater.Core.Test.Updater;
8
9
  using NuGetUpdater.Core.Updater;
9
10
 
@@ -2282,13 +2283,13 @@ public partial class UpdateWorkerTests
2282
2283
  await MockNuGetPackagesInDirectory(packages, Path.Combine(temporaryDirectory.DirectoryPath, "packages"));
2283
2284
  var resultOutputPath = Path.Combine(temporaryDirectory.DirectoryPath, "result.json");
2284
2285
 
2285
- var worker = new UpdaterWorker(new ExperimentsManager(), new TestLogger());
2286
+ var worker = new UpdaterWorker("TEST-JOB-ID", new ExperimentsManager(), new TestLogger());
2286
2287
  await worker.RunAsync(temporaryDirectory.DirectoryPath, "project.csproj", "Some.Package", "1.0.0", "1.1.0", isTransitive: false, resultOutputPath: resultOutputPath);
2287
2288
 
2288
2289
  var resultContents = await File.ReadAllTextAsync(resultOutputPath);
2289
- var result = JsonSerializer.Deserialize<UpdateOperationResult>(resultContents, UpdaterWorker.SerializerOptions)!;
2290
- Assert.Equal(ErrorType.MissingFile, result.ErrorType);
2291
- Assert.Equal(Path.Combine(temporaryDirectory.DirectoryPath, "this.file.does.not.exist.targets"), result.ErrorDetails!.ToString());
2290
+ var rawResult = JsonDocument.Parse(resultContents);
2291
+ Assert.Equal("dependency_file_not_found", rawResult.RootElement.GetProperty("Error").GetProperty("error-type").GetString());
2292
+ Assert.Equal(Path.Combine(temporaryDirectory.DirectoryPath, "this.file.does.not.exist.targets").NormalizePathToUnix(), rawResult.RootElement.GetProperty("Error").GetProperty("error-details").GetProperty("file-path").GetString());
2292
2293
  }
2293
2294
 
2294
2295
  [Fact]
@@ -2338,13 +2339,13 @@ public partial class UpdateWorkerTests
2338
2339
  await MockNuGetPackagesInDirectory(packages, Path.Combine(temporaryDirectory.DirectoryPath, "packages"));
2339
2340
  var resultOutputPath = Path.Combine(temporaryDirectory.DirectoryPath, "result.json");
2340
2341
 
2341
- var worker = new UpdaterWorker(new ExperimentsManager(), new TestLogger());
2342
+ var worker = new UpdaterWorker("TEST-JOB-ID", new ExperimentsManager(), new TestLogger());
2342
2343
  await worker.RunAsync(temporaryDirectory.DirectoryPath, "project.csproj", "Some.Package", "1.0.0", "1.1.0", isTransitive: false, resultOutputPath: resultOutputPath);
2343
2344
 
2344
2345
  var resultContents = await File.ReadAllTextAsync(resultOutputPath);
2345
- var result = JsonSerializer.Deserialize<UpdateOperationResult>(resultContents, UpdaterWorker.SerializerOptions)!;
2346
- Assert.Equal(ErrorType.MissingFile, result.ErrorType);
2347
- Assert.Equal("$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v$(VisualStudioVersion)/Some.Visual.Studio.Component.props", result.ErrorDetails!.ToString().NormalizePathToUnix());
2346
+ var rawResult = JsonDocument.Parse(resultContents);
2347
+ Assert.Equal("dependency_file_not_found", rawResult.RootElement.GetProperty("Error").GetProperty("error-type").GetString());
2348
+ Assert.Equal("$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v$(VisualStudioVersion)/Some.Visual.Studio.Component.props", rawResult.RootElement.GetProperty("Error").GetProperty("error-details").GetProperty("file-path").GetString());
2348
2349
  }
2349
2350
 
2350
2351
  [Theory]
@@ -2424,8 +2425,7 @@ public partial class UpdateWorkerTests
2424
2425
  """,
2425
2426
  expectedResult: new()
2426
2427
  {
2427
- ErrorType = ErrorType.AuthenticationFailure,
2428
- ErrorDetails = $"({http.BaseUrl.TrimEnd('/')}/index.json)",
2428
+ Error = new PrivateSourceAuthenticationFailure([$"{http.BaseUrl.TrimEnd('/')}/index.json"]),
2429
2429
  }
2430
2430
  );
2431
2431
  }
@@ -2555,8 +2555,7 @@ public partial class UpdateWorkerTests
2555
2555
  """,
2556
2556
  expectedResult: new()
2557
2557
  {
2558
- ErrorType = ErrorType.Unknown,
2559
- ErrorDetailsRegex = "Response status code does not indicate success",
2558
+ ErrorRegex = "Response status code does not indicate success",
2560
2559
  }
2561
2560
  );
2562
2561
  }
@@ -2633,8 +2632,7 @@ public partial class UpdateWorkerTests
2633
2632
  """,
2634
2633
  expectedResult: new()
2635
2634
  {
2636
- ErrorType = ErrorType.UpdateNotPossible,
2637
- ErrorDetails = new[] { "Unrelated.Package.1.0.0" },
2635
+ Error = new UpdateNotPossible(["Unrelated.Package.1.0.0"]),
2638
2636
  }
2639
2637
  );
2640
2638
  }
@@ -1,4 +1,3 @@
1
-
2
1
  Microsoft Visual Studio Solution File, Format Version 12.00
3
2
  # Visual Studio Version 17
4
3
  VisualStudioVersion = 17.5.33516.290
@@ -43,6 +42,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Versioning", "NuGetPr
43
42
  EndProject
44
43
  Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetUpdater.Cli.Test", "NuGetUpdater.Cli.Test\NuGetUpdater.Cli.Test.csproj", "{BDBEBF91-F5FD-4589-B4FB-B3DE3103B04B}"
45
44
  EndProject
45
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetPackageCorrelation", "DotNetPackageCorrelation\DotNetPackageCorrelation.csproj", "{52A6437B-7E72-4CCF-8E1E-355000F5DC10}"
46
+ EndProject
47
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetPackageCorrelation.Test", "DotNetPackageCorrelation.Test\DotNetPackageCorrelation.Test.csproj", "{0945703C-C8DC-44F0-B1D8-0EFE011411AE}"
48
+ EndProject
49
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetPackageCorrelation.Cli", "DotNetPackageCorrelation.Cli\DotNetPackageCorrelation.Cli.csproj", "{509454EE-629F-4767-B1D4-7F2DF86C11B5}"
50
+ EndProject
46
51
  Global
47
52
  GlobalSection(SolutionConfigurationPlatforms) = preSolution
48
53
  Debug|Any CPU = Debug|Any CPU
@@ -125,6 +130,18 @@ Global
125
130
  {BDBEBF91-F5FD-4589-B4FB-B3DE3103B04B}.Debug|Any CPU.Build.0 = Debug|Any CPU
126
131
  {BDBEBF91-F5FD-4589-B4FB-B3DE3103B04B}.Release|Any CPU.ActiveCfg = Release|Any CPU
127
132
  {BDBEBF91-F5FD-4589-B4FB-B3DE3103B04B}.Release|Any CPU.Build.0 = Release|Any CPU
133
+ {52A6437B-7E72-4CCF-8E1E-355000F5DC10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
134
+ {52A6437B-7E72-4CCF-8E1E-355000F5DC10}.Debug|Any CPU.Build.0 = Debug|Any CPU
135
+ {52A6437B-7E72-4CCF-8E1E-355000F5DC10}.Release|Any CPU.ActiveCfg = Release|Any CPU
136
+ {52A6437B-7E72-4CCF-8E1E-355000F5DC10}.Release|Any CPU.Build.0 = Release|Any CPU
137
+ {0945703C-C8DC-44F0-B1D8-0EFE011411AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
138
+ {0945703C-C8DC-44F0-B1D8-0EFE011411AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
139
+ {0945703C-C8DC-44F0-B1D8-0EFE011411AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
140
+ {0945703C-C8DC-44F0-B1D8-0EFE011411AE}.Release|Any CPU.Build.0 = Release|Any CPU
141
+ {509454EE-629F-4767-B1D4-7F2DF86C11B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
142
+ {509454EE-629F-4767-B1D4-7F2DF86C11B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
143
+ {509454EE-629F-4767-B1D4-7F2DF86C11B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
144
+ {509454EE-629F-4767-B1D4-7F2DF86C11B5}.Release|Any CPU.Build.0 = Release|Any CPU
128
145
  EndGlobalSection
129
146
  GlobalSection(SolutionProperties) = preSolution
130
147
  HideSolutionNode = FALSE