dependabot-nuget 0.285.0 → 0.287.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/NuGetProjects/Directory.Build.props +5 -1
  3. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.CommandLine/NuGet.CommandLine.csproj +1 -0
  4. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Configuration/NuGet.Configuration.csproj +1 -0
  5. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.LibraryModel/NuGet.LibraryModel.csproj +1 -0
  6. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj +1 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +8 -1
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +7 -3
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +11 -0
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +2 -2
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -5
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +15 -4
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +9 -38
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +10 -8
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +52 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +15 -8
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IAnalyzeWorker.cs +9 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IDiscoveryWorker.cs +8 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IUpdaterWorker.cs +9 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +78 -61
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +21 -10
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +37 -5
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +5 -3
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +5 -6
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +51 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +302 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +269 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +577 -43
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +168 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestAnalyzeWorker.cs +37 -0
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestDiscoveryWorker.cs +35 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestUpdaterWorker.cs +39 -0
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +104 -3
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +51 -13
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +4 -2
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +62 -18
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -1
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +14 -0
  39. data/helpers/lib/NuGetUpdater/global.json +1 -1
  40. data/lib/dependabot/nuget/file_updater.rb +8 -3
  41. data/lib/dependabot/nuget/native_helpers.rb +11 -12
  42. metadata +12 -6
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolverEnvironment.cs +0 -12
@@ -1,10 +1,14 @@
1
+ using System.Net;
1
2
  using System.Text;
2
3
  using System.Text.Json;
3
4
  using System.Xml.Linq;
4
5
 
6
+ using NuGetUpdater.Core.Analyze;
7
+ using NuGetUpdater.Core.Discover;
5
8
  using NuGetUpdater.Core.Run;
6
9
  using NuGetUpdater.Core.Run.ApiModel;
7
10
  using NuGetUpdater.Core.Test.Update;
11
+ using NuGetUpdater.Core.Updater;
8
12
 
9
13
  using Xunit;
10
14
 
@@ -17,13 +21,8 @@ public class RunWorkerTests
17
21
  [Fact]
18
22
  public async Task UpdateSinglePackageProducedExpectedAPIMessages()
19
23
  {
20
- var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
21
24
  await RunAsync(
22
- packages:
23
- [
24
- MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", additionalMetadata: [repoMetadata]),
25
- MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net8.0", additionalMetadata: [repoMetadata]),
26
- ],
25
+ packages: [],
27
26
  job: new Job()
28
27
  {
29
28
  Source = new()
@@ -50,6 +49,55 @@ public class RunWorkerTests
50
49
  </Project>
51
50
  """)
52
51
  ],
52
+ discoveryWorker: new TestDiscoveryWorker(_input =>
53
+ {
54
+ return Task.FromResult(new WorkspaceDiscoveryResult()
55
+ {
56
+ Path = "some-dir",
57
+ Projects =
58
+ [
59
+ new()
60
+ {
61
+ FilePath = "project.csproj",
62
+ TargetFrameworks = ["net8.0"],
63
+ Dependencies =
64
+ [
65
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
66
+ ]
67
+ }
68
+ ]
69
+ });
70
+ }),
71
+ analyzeWorker: new TestAnalyzeWorker(input =>
72
+ {
73
+ return Task.FromResult(new AnalysisResult()
74
+ {
75
+ UpdatedVersion = "1.0.1",
76
+ CanUpdate = true,
77
+ UpdatedDependencies =
78
+ [
79
+ new("Some.Package", "1.0.2", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
80
+ ]
81
+ });
82
+ }),
83
+ updaterWorker: new TestUpdaterWorker(async input =>
84
+ {
85
+ Assert.Equal("Some.Package", input.Item3);
86
+ Assert.Equal("1.0.0", input.Item4);
87
+ Assert.Equal("1.0.1", input.Item5);
88
+ var projectPath = input.Item1 + input.Item2;
89
+ await File.WriteAllTextAsync(projectPath, """
90
+ <Project Sdk="Microsoft.NET.Sdk">
91
+ <PropertyGroup>
92
+ <TargetFramework>net8.0</TargetFramework>
93
+ </PropertyGroup>
94
+ <ItemGroup>
95
+ <PackageReference Include="Some.Package" Version="1.0.1" />
96
+ </ItemGroup>
97
+ </Project>
98
+ """);
99
+ return new UpdateOperationResult();
100
+ }),
53
101
  expectedResult: new RunResult()
54
102
  {
55
103
  Base64DependencyFiles =
@@ -166,39 +214,258 @@ public class RunWorkerTests
166
214
  }
167
215
 
168
216
  [Fact]
169
- public async Task PrivateSourceAuthenticationFailureIsForwaredToApiHandler()
217
+ public async Task UpdateHandlesSemicolonsInPackageReference()
170
218
  {
171
- static (int, string) TestHttpHandler(string uriString)
172
- {
173
- var uri = new Uri(uriString, UriKind.Absolute);
174
- var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
175
- return uri.PathAndQuery switch
219
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
220
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
221
+ await RunAsync(
222
+ packages:
223
+ [
224
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", additionalMetadata: [repoMetadata]),
225
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net8.0", additionalMetadata: [repoMetadata]),
226
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "1.0.0", "net8.0", additionalMetadata: [repoMetadata2]),
227
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "1.0.1", "net8.0", additionalMetadata: [repoMetadata2]),
228
+ ],
229
+ job: new Job()
230
+ {
231
+ PackageManager = "nuget",
232
+ Source = new()
233
+ {
234
+ Provider = "github",
235
+ Repo = "test/repo",
236
+ Directory = "some-dir",
237
+ },
238
+ AllowedUpdates =
239
+ [
240
+ new() { UpdateType = "all" }
241
+ ]
242
+ },
243
+ files:
244
+ [
245
+ ("some-dir/project.csproj", """
246
+ <Project Sdk="Microsoft.NET.Sdk">
247
+ <PropertyGroup>
248
+ <TargetFramework>net8.0</TargetFramework>
249
+ </PropertyGroup>
250
+ <ItemGroup>
251
+ <PackageReference Include="Some.Package;Some.Package2" Version="1.0.0" />
252
+ </ItemGroup>
253
+ </Project>
254
+ """)
255
+ ],
256
+ discoveryWorker: new TestDiscoveryWorker(_input =>
176
257
  {
177
- // initial request is good
178
- "/index.json" => (200, $$"""
258
+ return Task.FromResult(new WorkspaceDiscoveryResult()
259
+ {
260
+ Path = "some-dir",
261
+ Projects =
262
+ [
263
+ new()
264
+ {
265
+ FilePath = "project.csproj",
266
+ TargetFrameworks = ["net8.0"],
267
+ Dependencies =
268
+ [
269
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
270
+ new("Some.Package2", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
271
+ ]
272
+ }
273
+ ]
274
+ });
275
+ }),
276
+ analyzeWorker: new TestAnalyzeWorker(input =>
277
+ {
278
+ return Task.FromResult(new AnalysisResult()
279
+ {
280
+ UpdatedVersion = "1.0.1",
281
+ CanUpdate = true,
282
+ UpdatedDependencies =
283
+ [
284
+ new("Some.Package", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
285
+ new("Some.Package2", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package2"),
286
+ ]
287
+ });
288
+ }),
289
+ updaterWorker: new TestUpdaterWorker(async input =>
290
+ {
291
+ Assert.Contains(input.Item3, ["Some.Package", "Some.Package2"]);
292
+ Assert.Equal("1.0.0", input.Item4);
293
+ Assert.Equal("1.0.1", input.Item5);
294
+ var projectPath = input.Item1 + input.Item2;
295
+ await File.WriteAllTextAsync(projectPath, """
296
+ <Project Sdk="Microsoft.NET.Sdk">
297
+ <PropertyGroup>
298
+ <TargetFramework>net8.0</TargetFramework>
299
+ </PropertyGroup>
300
+ <ItemGroup>
301
+ <PackageReference Include="Some.Package;Some.Package2" Version="1.0.1" />
302
+ </ItemGroup>
303
+ </Project>
304
+ """);
305
+ return new UpdateOperationResult();
306
+ }),
307
+ expectedResult: new RunResult()
308
+ {
309
+ Base64DependencyFiles =
310
+ [
311
+ new DependencyFile()
312
+ {
313
+ Directory = "/some-dir",
314
+ Name = "project.csproj",
315
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
316
+ <Project Sdk="Microsoft.NET.Sdk">
317
+ <PropertyGroup>
318
+ <TargetFramework>net8.0</TargetFramework>
319
+ </PropertyGroup>
320
+ <ItemGroup>
321
+ <PackageReference Include="Some.Package;Some.Package2" Version="1.0.0" />
322
+ </ItemGroup>
323
+ </Project>
324
+ """))
325
+ }
326
+ ],
327
+ BaseCommitSha = "TEST-COMMIT-SHA",
328
+ },
329
+ expectedApiMessages:
330
+ [
331
+ new UpdatedDependencyList()
332
+ {
333
+ Dependencies =
334
+ [
335
+ new ReportedDependency()
336
+ {
337
+ Name = "Some.Package",
338
+ Version = "1.0.0",
339
+ Requirements =
340
+ [
341
+ new ReportedRequirement()
342
+ {
343
+ Requirement = "1.0.0",
344
+ File = "/some-dir/project.csproj",
345
+ Groups = ["dependencies"],
346
+ }
347
+ ]
348
+ },
349
+ new ReportedDependency()
350
+ {
351
+ Name = "Some.Package2",
352
+ Version = "1.0.0",
353
+ Requirements =
354
+ [
355
+ new ReportedRequirement()
356
+ {
357
+ Requirement = "1.0.0",
358
+ File = "/some-dir/project.csproj",
359
+ Groups = ["dependencies"],
360
+ }
361
+ ]
362
+ },
363
+ ],
364
+ DependencyFiles = ["/some-dir/project.csproj"],
365
+ },
366
+ new IncrementMetric()
367
+ {
368
+ Metric = "updater.started",
369
+ Tags = new()
179
370
  {
180
- "version": "3.0.0",
181
- "resources": [
182
- {
183
- "@id": "{{baseUrl}}/download",
184
- "@type": "PackageBaseAddress/3.0.0"
185
- },
186
- {
187
- "@id": "{{baseUrl}}/query",
188
- "@type": "SearchQueryService"
189
- },
190
- {
191
- "@id": "{{baseUrl}}/registrations",
192
- "@type": "RegistrationsBaseUrl"
193
- }
194
- ]
371
+ ["operation"] = "group_update_all_versions"
195
372
  }
196
- """),
197
- // all other requests are unauthorized
198
- _ => (401, "{}"),
199
- };
200
- }
201
- using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
373
+ },
374
+ new CreatePullRequest()
375
+ {
376
+ Dependencies =
377
+ [
378
+ new ReportedDependency()
379
+ {
380
+ Name = "Some.Package",
381
+ Version = "1.0.1",
382
+ Requirements =
383
+ [
384
+ new ReportedRequirement()
385
+ {
386
+ Requirement = "1.0.1",
387
+ File = "/some-dir/project.csproj",
388
+ Groups = ["dependencies"],
389
+ Source = new()
390
+ {
391
+ SourceUrl = "https://nuget.example.com/some-package",
392
+ Type = "nuget_repo",
393
+ }
394
+ }
395
+ ],
396
+ PreviousVersion = "1.0.0",
397
+ PreviousRequirements =
398
+ [
399
+ new ReportedRequirement()
400
+ {
401
+ Requirement = "1.0.0",
402
+ File = "/some-dir/project.csproj",
403
+ Groups = ["dependencies"],
404
+ }
405
+ ],
406
+ },
407
+ new ReportedDependency()
408
+ {
409
+ Name = "Some.Package2",
410
+ Version = "1.0.1",
411
+ Requirements =
412
+ [
413
+ new ReportedRequirement()
414
+ {
415
+ Requirement = "1.0.1",
416
+ File = "/some-dir/project.csproj",
417
+ Groups = ["dependencies"],
418
+ Source = new()
419
+ {
420
+ SourceUrl = "https://nuget.example.com/some-package2",
421
+ Type = "nuget_repo",
422
+ }
423
+ }
424
+ ],
425
+ PreviousVersion = "1.0.0",
426
+ PreviousRequirements =
427
+ [
428
+ new ReportedRequirement()
429
+ {
430
+ Requirement = "1.0.0",
431
+ File = "/some-dir/project.csproj",
432
+ Groups = ["dependencies"],
433
+ }
434
+ ],
435
+ },
436
+ ],
437
+ UpdatedDependencyFiles =
438
+ [
439
+ new DependencyFile()
440
+ {
441
+ Name = "project.csproj",
442
+ Directory = "/some-dir",
443
+ Content = """
444
+ <Project Sdk="Microsoft.NET.Sdk">
445
+ <PropertyGroup>
446
+ <TargetFramework>net8.0</TargetFramework>
447
+ </PropertyGroup>
448
+ <ItemGroup>
449
+ <PackageReference Include="Some.Package;Some.Package2" Version="1.0.1" />
450
+ </ItemGroup>
451
+ </Project>
452
+ """,
453
+ }
454
+
455
+ ],
456
+ BaseCommitSha = "TEST-COMMIT-SHA",
457
+ CommitMessage = "TODO: message",
458
+ PrTitle = "TODO: title",
459
+ PrBody = "TODO: body",
460
+ },
461
+ new MarkAsProcessed("TEST-COMMIT-SHA")
462
+ ]
463
+ );
464
+ }
465
+
466
+ [Fact]
467
+ public async Task PrivateSourceAuthenticationFailureIsForwaredToApiHandler()
468
+ {
202
469
  await RunAsync(
203
470
  packages:
204
471
  [
@@ -218,11 +485,11 @@ public class RunWorkerTests
218
485
  },
219
486
  files:
220
487
  [
221
- ("NuGet.Config", $"""
488
+ ("NuGet.Config", """
222
489
  <configuration>
223
490
  <packageSources>
224
491
  <clear />
225
- <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
492
+ <add key="private_feed" value="http://example.com/nuget/index.json" allowInsecureConnections="true" />
226
493
  </packageSources>
227
494
  </configuration>
228
495
  """),
@@ -237,6 +504,12 @@ public class RunWorkerTests
237
504
  </Project>
238
505
  """)
239
506
  ],
507
+ discoveryWorker: new TestDiscoveryWorker((_input) =>
508
+ {
509
+ throw new HttpRequestException(message: null, inner: null, statusCode: HttpStatusCode.Unauthorized);
510
+ }),
511
+ analyzeWorker: TestAnalyzeWorker.FromResults(),
512
+ updaterWorker: TestUpdaterWorker.FromResults(),
240
513
  expectedResult: new RunResult()
241
514
  {
242
515
  Base64DependencyFiles = [],
@@ -244,7 +517,7 @@ public class RunWorkerTests
244
517
  },
245
518
  expectedApiMessages:
246
519
  [
247
- new PrivateSourceAuthenticationFailure([$"{http.BaseUrl.TrimEnd('/')}/index.json"]),
520
+ new PrivateSourceAuthenticationFailure(["http://example.com/nuget/index.json"]),
248
521
  new MarkAsProcessed("TEST-COMMIT-SHA")
249
522
  ]
250
523
  );
@@ -296,6 +569,107 @@ public class RunWorkerTests
296
569
  </packages>
297
570
  """),
298
571
  ],
572
+ discoveryWorker: new TestDiscoveryWorker(_input =>
573
+ {
574
+ return Task.FromResult(new WorkspaceDiscoveryResult()
575
+ {
576
+ Path = "some-dir",
577
+ Projects =
578
+ [
579
+ new()
580
+ {
581
+ FilePath = "project.csproj",
582
+ TargetFrameworks = ["net8.0"],
583
+ Dependencies =
584
+ [
585
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
586
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
587
+ ]
588
+ }
589
+ ]
590
+ });
591
+ }),
592
+ analyzeWorker: new TestAnalyzeWorker(input =>
593
+ {
594
+ var result = input.Item3.Name switch
595
+ {
596
+ "Some.Package" => new AnalysisResult()
597
+ {
598
+ CanUpdate = true,
599
+ UpdatedVersion = "1.0.1",
600
+ UpdatedDependencies =
601
+ [
602
+ new("Some.Package", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
603
+ ]
604
+ },
605
+ "Some.Package2" => new AnalysisResult()
606
+ {
607
+ CanUpdate = true,
608
+ UpdatedVersion = "2.0.1",
609
+ UpdatedDependencies =
610
+ [
611
+ new("Some.Package2", "2.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package2"),
612
+ ]
613
+ },
614
+ _ => throw new NotSupportedException(),
615
+ };
616
+ return Task.FromResult(result);
617
+ }),
618
+ updaterWorker: new TestUpdaterWorker(async input =>
619
+ {
620
+ var repoRootPath = input.Item1;
621
+ var filePath = input.Item2;
622
+ var packageName = input.Item3;
623
+ var previousVersion = input.Item4;
624
+ var newVersion = input.Item5;
625
+ var _isTransitive = input.Item6;
626
+
627
+ var projectPath = Path.Join(repoRootPath, filePath);
628
+ switch (packageName)
629
+ {
630
+ case "Some.Package":
631
+ await File.WriteAllTextAsync(projectPath, """
632
+ <Project Sdk="Microsoft.NET.Sdk">
633
+ <PropertyGroup>
634
+ <TargetFramework>net8.0</TargetFramework>
635
+ </PropertyGroup>
636
+ <ItemGroup>
637
+ <PackageReference Include="Some.Package" Version="1.0.1" />
638
+ </ItemGroup>
639
+ </Project>
640
+ """);
641
+ break;
642
+ case "Some.Package2":
643
+ await File.WriteAllTextAsync(projectPath, """
644
+ <Project Sdk="Microsoft.NET.Sdk">
645
+ <PropertyGroup>
646
+ <TargetFramework>net8.0</TargetFramework>
647
+ </PropertyGroup>
648
+ <ItemGroup>
649
+ <PackageReference Include="Some.Package" Version="1.0.1" />
650
+ </ItemGroup>
651
+ <ItemGroup>
652
+ <Reference Include="Some.Package2">
653
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
654
+ <Private>True</Private>
655
+ </Reference>
656
+ </ItemGroup>
657
+ </Project>
658
+ """);
659
+ var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath)!, "packages.config");
660
+ await File.WriteAllTextAsync(packagesConfigPath, """
661
+ <?xml version="1.0" encoding="utf-8"?>
662
+ <packages>
663
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
664
+ </packages>
665
+ """);
666
+ break;
667
+ default:
668
+ throw new NotSupportedException();
669
+ }
670
+
671
+ return new UpdateOperationResult();
672
+ }),
299
673
  expectedResult: new RunResult()
300
674
  {
301
675
  Base64DependencyFiles =
@@ -547,6 +921,160 @@ public class RunWorkerTests
547
921
  </packages>
548
922
  """),
549
923
  ],
924
+ discoveryWorker: new TestDiscoveryWorker(_input =>
925
+ {
926
+ return Task.FromResult(new WorkspaceDiscoveryResult()
927
+ {
928
+ Path = "some-dir/ProjectA",
929
+ Projects =
930
+ [
931
+ new()
932
+ {
933
+ FilePath = "../ProjectB/ProjectB.csproj",
934
+ TargetFrameworks = ["net8.0"],
935
+ Dependencies =
936
+ [
937
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
938
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
939
+ ]
940
+ },
941
+ new()
942
+ {
943
+ FilePath = "ProjectA.csproj",
944
+ TargetFrameworks = ["net8.0"],
945
+ Dependencies =
946
+ [
947
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
948
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
949
+ ]
950
+ }
951
+ ]
952
+ });
953
+ }),
954
+ analyzeWorker: new TestAnalyzeWorker(input =>
955
+ {
956
+ var result = input.Item3.Name switch
957
+ {
958
+ "Some.Package" => new AnalysisResult()
959
+ {
960
+ CanUpdate = true,
961
+ UpdatedVersion = "1.0.1",
962
+ UpdatedDependencies =
963
+ [
964
+ new("Some.Package", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
965
+ ]
966
+ },
967
+ "Some.Package2" => new AnalysisResult()
968
+ {
969
+ CanUpdate = true,
970
+ UpdatedVersion = "2.0.1",
971
+ UpdatedDependencies =
972
+ [
973
+ new("Some.Package2", "2.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package2"),
974
+ ]
975
+ },
976
+ _ => throw new NotSupportedException(),
977
+ };
978
+ return Task.FromResult(result);
979
+ }),
980
+ updaterWorker: new TestUpdaterWorker(async input =>
981
+ {
982
+ var repoRootPath = input.Item1;
983
+ var filePath = input.Item2;
984
+ var packageName = input.Item3;
985
+ var previousVersion = input.Item4;
986
+ var newVersion = input.Item5;
987
+ var _isTransitive = input.Item6;
988
+
989
+ var projectPath = Path.Join(repoRootPath, filePath);
990
+ var projectName = Path.GetFileName(projectPath);
991
+ var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath)!, "packages.config");
992
+ switch ((projectName, packageName))
993
+ {
994
+ case ("ProjectA.csproj", "Some.Package"):
995
+ await File.WriteAllTextAsync(projectPath, """
996
+ <Project Sdk="Microsoft.NET.Sdk">
997
+ <PropertyGroup>
998
+ <TargetFramework>net8.0</TargetFramework>
999
+ </PropertyGroup>
1000
+ <ItemGroup>
1001
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1002
+ </ItemGroup>
1003
+ <ItemGroup>
1004
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
1005
+ </ItemGroup>
1006
+ </Project>
1007
+ """);
1008
+ break;
1009
+ case ("ProjectA.csproj", "Some.Package2"):
1010
+ await File.WriteAllTextAsync(projectPath, """
1011
+ <Project Sdk="Microsoft.NET.Sdk">
1012
+ <PropertyGroup>
1013
+ <TargetFramework>net8.0</TargetFramework>
1014
+ </PropertyGroup>
1015
+ <ItemGroup>
1016
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1017
+ </ItemGroup>
1018
+ <ItemGroup>
1019
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
1020
+ </ItemGroup>
1021
+ <ItemGroup>
1022
+ <Reference Include="Some.Package2">
1023
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
1024
+ <Private>True</Private>
1025
+ </Reference>
1026
+ </ItemGroup>
1027
+ </Project>
1028
+ """);
1029
+ await File.WriteAllTextAsync(packagesConfigPath, """
1030
+ <?xml version="1.0" encoding="utf-8"?>
1031
+ <packages>
1032
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1033
+ </packages>
1034
+ """);
1035
+ break;
1036
+ case ("ProjectB.csproj", "Some.Package"):
1037
+ await File.WriteAllTextAsync(projectPath, """
1038
+ <Project Sdk="Microsoft.NET.Sdk">
1039
+ <PropertyGroup>
1040
+ <TargetFramework>net8.0</TargetFramework>
1041
+ </PropertyGroup>
1042
+ <ItemGroup>
1043
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1044
+ </ItemGroup>
1045
+ </Project>
1046
+ """);
1047
+ break;
1048
+ case ("ProjectB.csproj", "Some.Package2"):
1049
+ await File.WriteAllTextAsync(projectPath, """
1050
+ <Project Sdk="Microsoft.NET.Sdk">
1051
+ <PropertyGroup>
1052
+ <TargetFramework>net8.0</TargetFramework>
1053
+ </PropertyGroup>
1054
+ <ItemGroup>
1055
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1056
+ </ItemGroup>
1057
+ <ItemGroup>
1058
+ <Reference Include="Some.Package2">
1059
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
1060
+ <Private>True</Private>
1061
+ </Reference>
1062
+ </ItemGroup>
1063
+ </Project>
1064
+ """);
1065
+ await File.WriteAllTextAsync(packagesConfigPath, """
1066
+ <?xml version="1.0" encoding="utf-8"?>
1067
+ <packages>
1068
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1069
+ </packages>
1070
+ """);
1071
+ break;
1072
+ default:
1073
+ throw new NotSupportedException();
1074
+ }
1075
+
1076
+ return new UpdateOperationResult();
1077
+ }),
550
1078
  expectedResult: new RunResult()
551
1079
  {
552
1080
  Base64DependencyFiles =
@@ -807,7 +1335,7 @@ public class RunWorkerTests
807
1335
  [
808
1336
  new DependencyFile()
809
1337
  {
810
- Name = "../ProjectB/ProjectB.csproj",
1338
+ Name = "ProjectB.csproj",
811
1339
  Directory = "/some-dir/ProjectB",
812
1340
  Content = """
813
1341
  <Project Sdk="Microsoft.NET.Sdk">
@@ -828,7 +1356,7 @@ public class RunWorkerTests
828
1356
  },
829
1357
  new DependencyFile()
830
1358
  {
831
- Name = "../ProjectB/packages.config",
1359
+ Name = "packages.config",
832
1360
  Directory = "/some-dir/ProjectB",
833
1361
  Content = """
834
1362
  <?xml version="1.0" encoding="utf-8"?>
@@ -883,7 +1411,7 @@ public class RunWorkerTests
883
1411
  );
884
1412
  }
885
1413
 
886
- private static async Task RunAsync(Job job, TestFile[] files, RunResult? expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, string? repoContentsPath = null)
1414
+ private static async Task RunAsync(Job job, TestFile[] files, IDiscoveryWorker? discoveryWorker, IAnalyzeWorker? analyzeWorker, IUpdaterWorker? updaterWorker, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, ExperimentsManager? experimentsManager = null, string? repoContentsPath = null)
887
1415
  {
888
1416
  // arrange
889
1417
  using var tempDirectory = new TemporaryDirectory();
@@ -898,9 +1426,15 @@ public class RunWorkerTests
898
1426
  }
899
1427
 
900
1428
  // act
1429
+ experimentsManager ??= new ExperimentsManager();
901
1430
  var testApiHandler = new TestApiHandler();
902
- var worker = new RunWorker(testApiHandler, new TestLogger());
903
- var repoContentsPathDirectoryInfo = new DirectoryInfo(repoContentsPath);
1431
+ var logger = new TestLogger();
1432
+ discoveryWorker ??= new DiscoveryWorker(logger);
1433
+ analyzeWorker ??= new AnalyzeWorker(logger);
1434
+ updaterWorker ??= new UpdaterWorker(experimentsManager, logger);
1435
+
1436
+ var worker = new RunWorker(testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);
1437
+ var repoContentsPathDirectoryInfo = new DirectoryInfo(tempDirectory.DirectoryPath);
904
1438
  var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA");
905
1439
  var actualApiMessages = testApiHandler.ReceivedMessages.ToArray();
906
1440