dependabot-nuget 0.291.0 → 0.293.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/.editorconfig +1 -0
  3. data/helpers/lib/NuGetUpdater/.gitignore +1 -0
  4. data/helpers/lib/NuGetUpdater/Directory.Build.props +1 -0
  5. data/helpers/lib/NuGetUpdater/Directory.Packages.props +2 -1
  6. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Correlator.cs +197 -0
  7. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/DotNetPackageCorrelation.csproj +12 -0
  8. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageMapper.cs +68 -0
  9. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/PackageSet.cs +11 -0
  10. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/Release.cs +25 -0
  11. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/ReleasesFile.cs +9 -0
  12. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/RuntimePackages.cs +11 -0
  13. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/Sdk.cs +13 -0
  14. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/SemVerComparer.cs +16 -0
  15. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/Model/SemVersionConverter.cs +42 -0
  16. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/DotNetPackageCorrelation.Cli.csproj +16 -0
  17. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +32 -0
  18. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/CorrelatorTests.cs +99 -0
  19. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/DotNetPackageCorrelation.Test.csproj +18 -0
  20. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/EndToEndTests.cs +30 -0
  21. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Test/RuntimePackagesTests.cs +206 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +6 -4
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +1 -1
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +19 -4
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +5 -5
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +17 -5
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +8 -1
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +128 -4
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +8 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +9 -7
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +4 -4
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/Extensions.cs +1 -1
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +19 -1
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/BadRequirementException.cs +9 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +40 -8
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +2 -2
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +65 -23
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +3 -3
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +99 -2
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/EnsureDotNetPackageCorrelation.targets +25 -0
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +15 -5
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/PackagesConfigBuildFile.cs +5 -1
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/MissingFileException.cs +2 -1
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NativeResult.cs +3 -3
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +4 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/BadRequirement.cs +10 -0
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +1 -1
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotFound.cs +7 -2
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotParseable.cs +15 -0
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +25 -2
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobRepoNotFound.cs +1 -4
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs +1 -1
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UnknownError.cs +6 -2
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdateNotPossible.cs +1 -1
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +9 -18
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/UnparseableFileException.cs +12 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +1 -1
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +21 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +6 -30
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/WebApplicationTargetsConditionPatcher.cs +12 -1
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +0 -7
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DotNetPackageCorrelationManager.cs +46 -0
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +59 -30
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +1 -1
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +4 -4
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +15 -4
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +15 -9
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +60 -2
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +20 -3
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +56 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +108 -0
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +16 -12
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +1 -0
  74. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +15 -28
  75. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +5 -4
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +84 -40
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +24 -0
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/ExpectedUpdateOperationResult.cs +1 -1
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +25 -11
  80. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +1 -1
  81. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +2 -2
  82. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.LockFile.cs +251 -0
  83. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +14 -8
  84. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +154 -9
  85. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +71 -15
  86. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +38 -20
  87. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/ProjectHelperTests.cs +65 -0
  88. data/helpers/lib/NuGetUpdater/NuGetUpdater.sln +18 -1
  89. data/helpers/lib/NuGetUpdater/global.json +1 -1
  90. data/lib/dependabot/nuget/language.rb +21 -5
  91. data/lib/dependabot/nuget/native_helpers.rb +41 -14
  92. data/lib/dependabot/nuget/package_manager.rb +4 -4
  93. metadata +30 -7
  94. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +0 -11
@@ -1,6 +1,5 @@
1
1
  using NuGet.Versioning;
2
2
 
3
- using NuGetUpdater.Core.Analyze;
4
3
  using NuGetUpdater.Core.Run;
5
4
  using NuGetUpdater.Core.Run.ApiModel;
6
5
  using NuGetUpdater.Core.Test.Utilities;
@@ -228,37 +227,33 @@ public class SerializationTests
228
227
  Assert.False(experimentsManager.UseDirectDiscovery);
229
228
  }
230
229
 
231
- [Fact]
232
- public async Task DeserializeExperimentsManager_UnsupportedJobFileShape_InfoIsReportedAndEmptyExperimentSetIsReturned()
230
+ [Theory]
231
+ [MemberData(nameof(DeserializeErrorTypesData))]
232
+ public void SerializeError(JobErrorBase error, string expectedSerialization)
233
233
  {
234
- // arrange
235
- using var tempDir = new TemporaryDirectory();
236
- var jobFilePath = Path.Combine(tempDir.DirectoryPath, "job.json");
237
- var jobContent = """
238
- {
239
- "this-is-not-a-job-and-parsing-will-fail-but-an-empty-experiment-set-should-sill-be-returned": {
240
- }
241
- }
242
- """;
243
- await File.WriteAllTextAsync(jobFilePath, jobContent);
244
- var capturingTestLogger = new CapturingTestLogger();
245
-
246
- // act - this is the entrypoint the update command uses to parse the job file
247
- var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobFilePath, capturingTestLogger);
234
+ if (error is UnknownError unknown)
235
+ {
236
+ // special case the exception's call stack to make it testable
237
+ unknown.Details["error-backtrace"] = "TEST-BACKTRACE";
238
+ }
248
239
 
249
- // assert
250
- Assert.False(experimentsManager.UseLegacyDependencySolver);
251
- Assert.False(experimentsManager.UseDirectDiscovery);
252
- Assert.Single(capturingTestLogger.Messages, m => m.Contains("Error deserializing job file"));
240
+ var actual = HttpApiHandler.Serialize(error);
241
+ Assert.Equal(expectedSerialization, actual);
253
242
  }
254
243
 
255
244
  [Fact]
256
- public void SerializeError()
245
+ public void SerializeError_AllErrorTypesHaveSerializationTests()
257
246
  {
258
- var error = new JobRepoNotFound("some message");
259
- var actual = HttpApiHandler.Serialize(error);
260
- var expected = """{"data":{"error-type":"job_repo_not_found","error-details":{"message":"some message"}}}""";
261
- Assert.Equal(expected, actual);
247
+ var untestedTypes = typeof(JobErrorBase).Assembly.GetTypes()
248
+ .Where(t => t.IsSubclassOf(typeof(JobErrorBase)))
249
+ .ToHashSet();
250
+ foreach (object?[] data in DeserializeErrorTypesData())
251
+ {
252
+ var testedErrorType = data[0]!.GetType();
253
+ untestedTypes.Remove(testedErrorType);
254
+ }
255
+
256
+ Assert.Empty(untestedTypes.Select(t => t.Name));
262
257
  }
263
258
 
264
259
  [Fact]
@@ -503,7 +498,9 @@ public class SerializationTests
503
498
  "repo": "some/repo"
504
499
  },
505
500
  "commit-message-options": {
506
- "prefix": "[SECURITY] "
501
+ "prefix": "[SECURITY] ",
502
+ "prefix-development": null,
503
+ "include-scope": true
507
504
  }
508
505
  }
509
506
  }
@@ -511,7 +508,66 @@ public class SerializationTests
511
508
  var jobWrapper = RunWorker.Deserialize(jsonWrapperJson)!;
512
509
  Assert.Equal("[SECURITY] ", jobWrapper.Job.CommitMessageOptions!.Prefix);
513
510
  Assert.Null(jobWrapper.Job.CommitMessageOptions!.PrefixDevelopment);
514
- Assert.Null(jobWrapper.Job.CommitMessageOptions!.IncludeScope);
511
+ Assert.True(jobWrapper.Job.CommitMessageOptions!.IncludeScope);
512
+ }
513
+
514
+ public static IEnumerable<object?[]> DeserializeErrorTypesData()
515
+ {
516
+ yield return
517
+ [
518
+ new BadRequirement("some message"),
519
+ """
520
+ {"data":{"error-type":"illformed_requirement","error-details":{"message":"some message"}}}
521
+ """
522
+ ];
523
+
524
+ yield return
525
+ [
526
+ new DependencyFileNotFound("/some/file", "some message"),
527
+ """
528
+ {"data":{"error-type":"dependency_file_not_found","error-details":{"message":"some message","file-path":"/some/file"}}}
529
+ """
530
+ ];
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
+
540
+ yield return
541
+ [
542
+ new JobRepoNotFound("some message"),
543
+ """
544
+ {"data":{"error-type":"job_repo_not_found","error-details":{"message":"some message"}}}
545
+ """
546
+ ];
547
+
548
+ yield return
549
+ [
550
+ new PrivateSourceAuthenticationFailure(["url1", "url2"]),
551
+ """
552
+ {"data":{"error-type":"private_source_authentication_failure","error-details":{"source":"(url1|url2)"}}}
553
+ """
554
+ ];
555
+
556
+ yield return
557
+ [
558
+ new UnknownError(new Exception("some message"), "JOB-ID"),
559
+ """
560
+ {"data":{"error-type":"unknown_error","error-details":{"error-class":"Exception","error-message":"some message","error-backtrace":"TEST-BACKTRACE","package-manager":"nuget","job-id":"JOB-ID"}}}
561
+ """
562
+ ];
563
+
564
+ yield return
565
+ [
566
+ new UpdateNotPossible(["dep1", "dep2"]),
567
+ """
568
+ {"data":{"error-type":"update_not_possible","error-details":{"dependencies":["dep1","dep2"]}}}
569
+ """
570
+ ];
515
571
  }
516
572
 
517
573
  public static IEnumerable<object?[]> DeserializeAllowedUpdatesData()
@@ -596,16 +652,4 @@ public class SerializationTests
596
652
  }
597
653
  ];
598
654
  }
599
-
600
- private class CapturingTestLogger : ILogger
601
- {
602
- private readonly List<string> _messages = new();
603
-
604
- public IReadOnlyList<string> Messages => _messages;
605
-
606
- public void LogRaw(string message)
607
- {
608
- _messages.Add(message);
609
- }
610
- }
611
655
  }
@@ -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
  }
@@ -47,7 +47,7 @@ public abstract class UpdateWorkerTestBase : TestBase
47
47
  {
48
48
  return useSolution
49
49
  ? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [(projectFilePath, projectContents)], projectFilesExpected: [(projectFilePath, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager)
50
- : TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile: (projectFilePath, projectContents), expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager);
50
+ : TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile: (projectFilePath, projectContents), expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, additionalChecks: null, packages: packages, experimentsManager: experimentsManager);
51
51
  }
52
52
 
53
53
  protected static Task TestUpdate(
@@ -65,7 +65,7 @@ public abstract class UpdateWorkerTestBase : TestBase
65
65
  {
66
66
  return useSolution
67
67
  ? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [projectFile], projectFilesExpected: [(projectFile.Path, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager)
68
- : TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile, expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager);
68
+ : TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile, expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, additionalChecks: null, packages: packages, experimentsManager: experimentsManager);
69
69
  }
70
70
 
71
71
  protected static Task TestNoChangeforProject(
@@ -101,6 +101,7 @@ public abstract class UpdateWorkerTestBase : TestBase
101
101
  bool isTransitive = false,
102
102
  TestFile[]? additionalFiles = null,
103
103
  TestFile[]? additionalFilesExpected = null,
104
+ Action<string>? additionalChecks = null,
104
105
  MockNuGetPackage[]? packages = null,
105
106
  ExperimentsManager? experimentsManager = null,
106
107
  string projectFilePath = "test-project.csproj",
@@ -114,6 +115,7 @@ public abstract class UpdateWorkerTestBase : TestBase
114
115
  isTransitive,
115
116
  additionalFiles,
116
117
  additionalFilesExpected,
118
+ additionalChecks,
117
119
  packages,
118
120
  experimentsManager,
119
121
  expectedResult);
@@ -127,6 +129,7 @@ public abstract class UpdateWorkerTestBase : TestBase
127
129
  bool isTransitive = false,
128
130
  TestFile[]? additionalFiles = null,
129
131
  TestFile[]? additionalFilesExpected = null,
132
+ Action<string>? additionalChecks = null,
130
133
  MockNuGetPackage[]? packages = null,
131
134
  ExperimentsManager? experimentsManager = null,
132
135
  ExpectedUpdateOperationResult? expectedResult = null)
@@ -149,12 +152,20 @@ public abstract class UpdateWorkerTestBase : TestBase
149
152
 
150
153
  // run update
151
154
  experimentsManager ??= new ExperimentsManager();
152
- var worker = new UpdaterWorker(experimentsManager, new TestLogger());
155
+ var worker = new UpdaterWorker("TEST-JOB-ID", experimentsManager, new TestLogger());
153
156
  var projectPath = placeFilesInSrc ? $"src/{projectFilePath}" : projectFilePath;
154
157
  var actualResult = await worker.RunWithErrorHandlingAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
155
- if (expectedResult is { })
158
+ ValidateUpdateOperationResult(expectedResult, actualResult!);
159
+
160
+ if (additionalChecks is not null)
156
161
  {
157
- ValidateUpdateOperationResult(expectedResult, actualResult!);
162
+ var sourcesDirectory = temporaryDirectory;
163
+ if (placeFilesInSrc)
164
+ {
165
+ sourcesDirectory = Path.Combine(temporaryDirectory, "src");
166
+ }
167
+
168
+ additionalChecks(sourcesDirectory);
158
169
  }
159
170
  });
160
171
 
@@ -167,16 +178,19 @@ public abstract class UpdateWorkerTestBase : TestBase
167
178
  AssertContainsFiles(expectedResultFiles, actualResult);
168
179
  }
169
180
 
170
- protected static void ValidateUpdateOperationResult(ExpectedUpdateOperationResult expectedResult, UpdateOperationResult actualResult)
181
+ protected static void ValidateUpdateOperationResult(ExpectedUpdateOperationResult? expectedResult, UpdateOperationResult actualResult)
171
182
  {
172
- Assert.Equal(expectedResult.ErrorType, actualResult.ErrorType);
173
- 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)
174
188
  {
175
- Assert.Matches(expectedResult.ErrorDetailsRegex, errorDetails);
189
+ ValidateErrorRegex(expectedResult.ErrorRegex, actualResult.Error);
176
190
  }
177
191
  else
178
192
  {
179
- Assert.Equivalent(expectedResult.ErrorDetails, actualResult.ErrorDetails);
193
+ Assert.Null(actualResult.Error);
180
194
  }
181
195
  }
182
196
 
@@ -256,7 +270,7 @@ public abstract class UpdateWorkerTestBase : TestBase
256
270
 
257
271
  experimentsManager ??= new ExperimentsManager();
258
272
  var slnPath = Path.Combine(temporaryDirectory, slnName);
259
- var worker = new UpdaterWorker(experimentsManager, new TestLogger());
273
+ var worker = new UpdaterWorker("TEST-JOB-ID", experimentsManager, new TestLogger());
260
274
  await worker.RunAsync(temporaryDirectory, slnPath, dependencyName, oldVersion, newVersion, isTransitive);
261
275
  });
262
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
 
@@ -69,10 +69,10 @@ public partial class UpdateWorkerTests
69
69
  <PropertyGroup>
70
70
  <TargetFramework>netstandard2.0</TargetFramework>
71
71
  </PropertyGroup>
72
-
72
+
73
73
  <ItemGroup>
74
74
  <PackageReference Include="Some.Package" Version="13.0.3" />
75
- </ItemGroup>>
75
+ </ItemGroup>
76
76
  </Project>
77
77
  """,
78
78
  additionalFiles:
@@ -0,0 +1,251 @@
1
+ using Xunit;
2
+
3
+ namespace NuGetUpdater.Core.Test.Update;
4
+
5
+ public partial class UpdateWorkerTests
6
+ {
7
+ public class LockFile : UpdateWorkerTestBase
8
+ {
9
+ [Fact]
10
+ public async Task UpdateSingleDependency()
11
+ {
12
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
13
+ packages:
14
+ [
15
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
16
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0"),
17
+ ],
18
+ // initial
19
+ projectContents: $"""
20
+ <Project Sdk="Microsoft.NET.Sdk">
21
+ <PropertyGroup>
22
+ <TargetFramework>net8.0</TargetFramework>
23
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
24
+ </PropertyGroup>
25
+
26
+ <ItemGroup>
27
+ <PackageReference Include="Some.Package" Version="1.0.0" />
28
+ </ItemGroup>
29
+ </Project>
30
+ """,
31
+ additionalFiles:
32
+ [
33
+ ("packages.lock.json", "{}")
34
+ ],
35
+ // expected
36
+ expectedProjectContents: $"""
37
+ <Project Sdk="Microsoft.NET.Sdk">
38
+ <PropertyGroup>
39
+ <TargetFramework>net8.0</TargetFramework>
40
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
41
+ </PropertyGroup>
42
+
43
+ <ItemGroup>
44
+ <PackageReference Include="Some.Package" Version="2.0.0" />
45
+ </ItemGroup>
46
+ </Project>
47
+ """,
48
+ additionalChecks: path =>
49
+ {
50
+ var lockContents = File.ReadAllText(Path.Combine(path, "packages.lock.json"));
51
+ Assert.Contains("\"resolved\": \"2.0.0\"", lockContents);
52
+ }
53
+ );
54
+ }
55
+
56
+ [Fact]
57
+ public async Task UpdateSingleDependency_CentralPackageManagement()
58
+ {
59
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
60
+ packages:
61
+ [
62
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
63
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0"),
64
+ ],
65
+ // initial
66
+ projectContents: $"""
67
+ <Project Sdk="Microsoft.NET.Sdk">
68
+ <PropertyGroup>
69
+ <TargetFramework>net8.0</TargetFramework>
70
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
71
+ </PropertyGroup>
72
+
73
+ <ItemGroup>
74
+ <PackageReference Include="Some.Package" />
75
+ </ItemGroup>
76
+ </Project>
77
+ """,
78
+ additionalFiles:
79
+ [
80
+ ("packages.lock.json", "{}"),
81
+ ("Directory.Packages.props", """
82
+ <Project>
83
+ <PropertyGroup>
84
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
85
+ </PropertyGroup>
86
+
87
+ <ItemGroup>
88
+ <PackageVersion Include="Some.Package" Version="1.0.0" />
89
+ </ItemGroup>
90
+ </Project>
91
+ """)
92
+ ],
93
+ // expected
94
+ expectedProjectContents: $"""
95
+ <Project Sdk="Microsoft.NET.Sdk">
96
+ <PropertyGroup>
97
+ <TargetFramework>net8.0</TargetFramework>
98
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
99
+ </PropertyGroup>
100
+
101
+ <ItemGroup>
102
+ <PackageReference Include="Some.Package" />
103
+ </ItemGroup>
104
+ </Project>
105
+ """,
106
+ additionalFilesExpected:
107
+ [
108
+ ("Directory.Packages.props", """
109
+ <Project>
110
+ <PropertyGroup>
111
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
112
+ </PropertyGroup>
113
+
114
+ <ItemGroup>
115
+ <PackageVersion Include="Some.Package" Version="2.0.0" />
116
+ </ItemGroup>
117
+ </Project>
118
+ """)
119
+ ],
120
+ additionalChecks: path =>
121
+ {
122
+ var lockContents = File.ReadAllText(Path.Combine(path, "packages.lock.json"));
123
+ Assert.Contains("\"resolved\": \"2.0.0\"", lockContents);
124
+ }
125
+ );
126
+ }
127
+
128
+ [Fact]
129
+ public async Task UpdateSingleDependency_WindowsSpecific()
130
+ {
131
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
132
+ packages:
133
+ [
134
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
135
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0"),
136
+ ],
137
+ // initial
138
+ projectContents: $"""
139
+ <Project Sdk="Microsoft.NET.Sdk">
140
+ <PropertyGroup>
141
+ <TargetFramework>net8.0-windows</TargetFramework>
142
+ <UseWindowsForms>true</UseWindowsForms>
143
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
144
+ </PropertyGroup>
145
+
146
+ <ItemGroup>
147
+ <PackageReference Include="Some.Package" Version="1.0.0" />
148
+ </ItemGroup>
149
+ </Project>
150
+ """,
151
+ additionalFiles:
152
+ [
153
+ ("packages.lock.json", "{}")
154
+ ],
155
+ // expected
156
+ expectedProjectContents: $"""
157
+ <Project Sdk="Microsoft.NET.Sdk">
158
+ <PropertyGroup>
159
+ <TargetFramework>net8.0-windows</TargetFramework>
160
+ <UseWindowsForms>true</UseWindowsForms>
161
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
162
+ </PropertyGroup>
163
+
164
+ <ItemGroup>
165
+ <PackageReference Include="Some.Package" Version="2.0.0" />
166
+ </ItemGroup>
167
+ </Project>
168
+ """,
169
+ additionalChecks: path =>
170
+ {
171
+ var lockContents = File.ReadAllText(Path.Combine(path, "packages.lock.json"));
172
+ Assert.Contains("\"resolved\": \"2.0.0\"", lockContents);
173
+ }
174
+ );
175
+ }
176
+
177
+ [Fact]
178
+ public async Task UpdateSingleDependency_CentralPackageManagement_WindowsSpecific()
179
+ {
180
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
181
+ packages:
182
+ [
183
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
184
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0"),
185
+ ],
186
+ // initial
187
+ projectContents: $"""
188
+ <Project Sdk="Microsoft.NET.Sdk">
189
+ <PropertyGroup>
190
+ <TargetFramework>net8.0-windows</TargetFramework>
191
+ <UseWindowsForms>true</UseWindowsForms>
192
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
193
+ </PropertyGroup>
194
+
195
+ <ItemGroup>
196
+ <PackageReference Include="Some.Package" />
197
+ </ItemGroup>
198
+ </Project>
199
+ """,
200
+ additionalFiles:
201
+ [
202
+ ("packages.lock.json", "{}"),
203
+ ("Directory.Packages.props", """
204
+ <Project>
205
+ <PropertyGroup>
206
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
207
+ </PropertyGroup>
208
+
209
+ <ItemGroup>
210
+ <PackageVersion Include="Some.Package" Version="1.0.0" />
211
+ </ItemGroup>
212
+ </Project>
213
+ """)
214
+ ],
215
+ // expected
216
+ expectedProjectContents: $"""
217
+ <Project Sdk="Microsoft.NET.Sdk">
218
+ <PropertyGroup>
219
+ <TargetFramework>net8.0-windows</TargetFramework>
220
+ <UseWindowsForms>true</UseWindowsForms>
221
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
222
+ </PropertyGroup>
223
+
224
+ <ItemGroup>
225
+ <PackageReference Include="Some.Package" />
226
+ </ItemGroup>
227
+ </Project>
228
+ """,
229
+ additionalFilesExpected:
230
+ [
231
+ ("Directory.Packages.props", """
232
+ <Project>
233
+ <PropertyGroup>
234
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
235
+ </PropertyGroup>
236
+
237
+ <ItemGroup>
238
+ <PackageVersion Include="Some.Package" Version="2.0.0" />
239
+ </ItemGroup>
240
+ </Project>
241
+ """)
242
+ ],
243
+ additionalChecks: path =>
244
+ {
245
+ var lockContents = File.ReadAllText(Path.Combine(path, "packages.lock.json"));
246
+ Assert.Contains("\"resolved\": \"2.0.0\"", lockContents);
247
+ }
248
+ );
249
+ }
250
+ }
251
+ }
@@ -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]