dependabot-nuget 0.285.0 → 0.287.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/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