dependabot-nuget 0.284.0 → 0.286.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) 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 +1 -1
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +2 -2
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +52 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IAnalyzeWorker.cs +9 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IDiscoveryWorker.cs +8 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/IUpdaterWorker.cs +9 -0
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +104 -33
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +6 -5
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +37 -5
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +5 -3
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +0 -5
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +2 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +975 -57
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +168 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +53 -6
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestAnalyzeWorker.cs +37 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestDiscoveryWorker.cs +35 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestUpdaterWorker.cs +39 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +104 -3
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +51 -13
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +4 -2
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +22 -17
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +1 -1
  33. data/lib/dependabot/nuget/file_updater.rb +8 -3
  34. data/lib/dependabot/nuget/native_helpers.rb +11 -12
  35. metadata +12 -6
  36. 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 =
@@ -142,7 +190,7 @@ public class RunWorkerTests
142
190
  new DependencyFile()
143
191
  {
144
192
  Name = "project.csproj",
145
- Directory = "some-dir",
193
+ Directory = "/some-dir",
146
194
  Content = """
147
195
  <Project Sdk="Microsoft.NET.Sdk">
148
196
  <PropertyGroup>
@@ -168,37 +216,6 @@ public class RunWorkerTests
168
216
  [Fact]
169
217
  public async Task PrivateSourceAuthenticationFailureIsForwaredToApiHandler()
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
176
- {
177
- // initial request is good
178
- "/index.json" => (200, $$"""
179
- {
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
- ]
195
- }
196
- """),
197
- // all other requests are unauthorized
198
- _ => (401, "{}"),
199
- };
200
- }
201
- using var http = TestHttpServer.CreateTestStringServer(TestHttpHandler);
202
219
  await RunAsync(
203
220
  packages:
204
221
  [
@@ -218,11 +235,11 @@ public class RunWorkerTests
218
235
  },
219
236
  files:
220
237
  [
221
- ("NuGet.Config", $"""
238
+ ("NuGet.Config", """
222
239
  <configuration>
223
240
  <packageSources>
224
241
  <clear />
225
- <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
242
+ <add key="private_feed" value="http://example.com/nuget/index.json" allowInsecureConnections="true" />
226
243
  </packageSources>
227
244
  </configuration>
228
245
  """),
@@ -237,6 +254,12 @@ public class RunWorkerTests
237
254
  </Project>
238
255
  """)
239
256
  ],
257
+ discoveryWorker: new TestDiscoveryWorker((_input) =>
258
+ {
259
+ throw new HttpRequestException(message: null, inner: null, statusCode: HttpStatusCode.Unauthorized);
260
+ }),
261
+ analyzeWorker: TestAnalyzeWorker.FromResults(),
262
+ updaterWorker: TestUpdaterWorker.FromResults(),
240
263
  expectedResult: new RunResult()
241
264
  {
242
265
  Base64DependencyFiles = [],
@@ -244,30 +267,925 @@ public class RunWorkerTests
244
267
  },
245
268
  expectedApiMessages:
246
269
  [
247
- new PrivateSourceAuthenticationFailure([$"{http.BaseUrl.TrimEnd('/')}/index.json"]),
270
+ new PrivateSourceAuthenticationFailure(["http://example.com/nuget/index.json"]),
248
271
  new MarkAsProcessed("TEST-COMMIT-SHA")
249
272
  ]
250
273
  );
251
274
  }
252
275
 
253
- private static async Task RunAsync(Job job, TestFile[] files, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null)
276
+ [Fact]
277
+ public async Task UpdateHandlesPackagesConfigFiles()
254
278
  {
255
- // arrange
256
- using var tempDirectory = new TemporaryDirectory();
257
- await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDirectory.DirectoryPath);
258
- foreach (var (path, content) in files)
259
- {
260
- var fullPath = Path.Combine(tempDirectory.DirectoryPath, path);
261
- var directory = Path.GetDirectoryName(fullPath)!;
262
- Directory.CreateDirectory(directory);
263
- await File.WriteAllTextAsync(fullPath, content);
264
- }
279
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
280
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
281
+ await RunAsync(
282
+ packages:
283
+ [
284
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", additionalMetadata: [repoMetadata]),
285
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net8.0", additionalMetadata: [repoMetadata]),
286
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "2.0.0", "net8.0", additionalMetadata: [repoMetadata2]),
287
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "2.0.1", "net8.0", additionalMetadata: [repoMetadata2]),
288
+ ],
289
+ job: new Job()
290
+ {
291
+ PackageManager = "nuget",
292
+ Source = new()
293
+ {
294
+ Provider = "github",
295
+ Repo = "test/repo",
296
+ Directory = "some-dir",
297
+ },
298
+ AllowedUpdates =
299
+ [
300
+ new() { UpdateType = "all" }
301
+ ]
302
+ },
303
+ files:
304
+ [
305
+ ("some-dir/project.csproj", """
306
+ <Project Sdk="Microsoft.NET.Sdk">
307
+ <PropertyGroup>
308
+ <TargetFramework>net8.0</TargetFramework>
309
+ </PropertyGroup>
310
+ <ItemGroup>
311
+ <PackageReference Include="Some.Package" Version="1.0.0" />
312
+ </ItemGroup>
313
+ </Project>
314
+ """),
315
+ ("some-dir/packages.config", """
316
+ <?xml version="1.0" encoding="utf-8"?>
317
+ <packages>
318
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
319
+ </packages>
320
+ """),
321
+ ],
322
+ discoveryWorker: new TestDiscoveryWorker(_input =>
323
+ {
324
+ return Task.FromResult(new WorkspaceDiscoveryResult()
325
+ {
326
+ Path = "some-dir",
327
+ Projects =
328
+ [
329
+ new()
330
+ {
331
+ FilePath = "project.csproj",
332
+ TargetFrameworks = ["net8.0"],
333
+ Dependencies =
334
+ [
335
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
336
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
337
+ ]
338
+ }
339
+ ]
340
+ });
341
+ }),
342
+ analyzeWorker: new TestAnalyzeWorker(input =>
343
+ {
344
+ var result = input.Item3.Name switch
345
+ {
346
+ "Some.Package" => new AnalysisResult()
347
+ {
348
+ CanUpdate = true,
349
+ UpdatedVersion = "1.0.1",
350
+ UpdatedDependencies =
351
+ [
352
+ new("Some.Package", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
353
+ ]
354
+ },
355
+ "Some.Package2" => new AnalysisResult()
356
+ {
357
+ CanUpdate = true,
358
+ UpdatedVersion = "2.0.1",
359
+ UpdatedDependencies =
360
+ [
361
+ new("Some.Package2", "2.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package2"),
362
+ ]
363
+ },
364
+ _ => throw new NotSupportedException(),
365
+ };
366
+ return Task.FromResult(result);
367
+ }),
368
+ updaterWorker: new TestUpdaterWorker(async input =>
369
+ {
370
+ var repoRootPath = input.Item1;
371
+ var filePath = input.Item2;
372
+ var packageName = input.Item3;
373
+ var previousVersion = input.Item4;
374
+ var newVersion = input.Item5;
375
+ var _isTransitive = input.Item6;
265
376
 
266
- // act
267
- var testApiHandler = new TestApiHandler();
268
- var worker = new RunWorker(testApiHandler, new TestLogger());
269
- var repoContentsPath = new DirectoryInfo(tempDirectory.DirectoryPath);
270
- var actualResult = await worker.RunAsync(job, repoContentsPath, "TEST-COMMIT-SHA");
377
+ var projectPath = Path.Join(repoRootPath, filePath);
378
+ switch (packageName)
379
+ {
380
+ case "Some.Package":
381
+ await File.WriteAllTextAsync(projectPath, """
382
+ <Project Sdk="Microsoft.NET.Sdk">
383
+ <PropertyGroup>
384
+ <TargetFramework>net8.0</TargetFramework>
385
+ </PropertyGroup>
386
+ <ItemGroup>
387
+ <PackageReference Include="Some.Package" Version="1.0.1" />
388
+ </ItemGroup>
389
+ </Project>
390
+ """);
391
+ break;
392
+ case "Some.Package2":
393
+ await File.WriteAllTextAsync(projectPath, """
394
+ <Project Sdk="Microsoft.NET.Sdk">
395
+ <PropertyGroup>
396
+ <TargetFramework>net8.0</TargetFramework>
397
+ </PropertyGroup>
398
+ <ItemGroup>
399
+ <PackageReference Include="Some.Package" Version="1.0.1" />
400
+ </ItemGroup>
401
+ <ItemGroup>
402
+ <Reference Include="Some.Package2">
403
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
404
+ <Private>True</Private>
405
+ </Reference>
406
+ </ItemGroup>
407
+ </Project>
408
+ """);
409
+ var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath)!, "packages.config");
410
+ await File.WriteAllTextAsync(packagesConfigPath, """
411
+ <?xml version="1.0" encoding="utf-8"?>
412
+ <packages>
413
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
414
+ </packages>
415
+ """);
416
+ break;
417
+ default:
418
+ throw new NotSupportedException();
419
+ }
420
+
421
+ return new UpdateOperationResult();
422
+ }),
423
+ expectedResult: new RunResult()
424
+ {
425
+ Base64DependencyFiles =
426
+ [
427
+ new DependencyFile()
428
+ {
429
+ Directory = "/some-dir",
430
+ Name = "project.csproj",
431
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
432
+ <Project Sdk="Microsoft.NET.Sdk">
433
+ <PropertyGroup>
434
+ <TargetFramework>net8.0</TargetFramework>
435
+ </PropertyGroup>
436
+ <ItemGroup>
437
+ <PackageReference Include="Some.Package" Version="1.0.0" />
438
+ </ItemGroup>
439
+ </Project>
440
+ """))
441
+ },
442
+ new DependencyFile()
443
+ {
444
+ Directory = "/some-dir",
445
+ Name = "packages.config",
446
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
447
+ <?xml version="1.0" encoding="utf-8"?>
448
+ <packages>
449
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
450
+ </packages>
451
+ """))
452
+ }
453
+ ],
454
+ BaseCommitSha = "TEST-COMMIT-SHA",
455
+ },
456
+ expectedApiMessages:
457
+ [
458
+ new UpdatedDependencyList()
459
+ {
460
+ Dependencies =
461
+ [
462
+ new ReportedDependency()
463
+ {
464
+ Name = "Some.Package",
465
+ Version = "1.0.0",
466
+ Requirements =
467
+ [
468
+ new ReportedRequirement()
469
+ {
470
+ Requirement = "1.0.0",
471
+ File = "/some-dir/project.csproj",
472
+ Groups = ["dependencies"],
473
+ }
474
+ ]
475
+ },
476
+ new ReportedDependency()
477
+ {
478
+ Name = "Some.Package2",
479
+ Version = "2.0.0",
480
+ Requirements =
481
+ [
482
+ new ReportedRequirement()
483
+ {
484
+ Requirement = "2.0.0",
485
+ File = "/some-dir/packages.config",
486
+ Groups = ["dependencies"],
487
+ }
488
+ ]
489
+ }
490
+ ],
491
+ DependencyFiles = ["/some-dir/project.csproj", "/some-dir/packages.config"],
492
+ },
493
+ new IncrementMetric()
494
+ {
495
+ Metric = "updater.started",
496
+ Tags = new()
497
+ {
498
+ ["operation"] = "group_update_all_versions"
499
+ }
500
+ },
501
+ new CreatePullRequest()
502
+ {
503
+ Dependencies =
504
+ [
505
+ new ReportedDependency()
506
+ {
507
+ Name = "Some.Package",
508
+ Version = "1.0.1",
509
+ Requirements =
510
+ [
511
+ new ReportedRequirement()
512
+ {
513
+ Requirement = "1.0.1",
514
+ File = "/some-dir/project.csproj",
515
+ Groups = ["dependencies"],
516
+ Source = new()
517
+ {
518
+ SourceUrl = "https://nuget.example.com/some-package",
519
+ Type = "nuget_repo",
520
+ }
521
+ }
522
+ ],
523
+ PreviousVersion = "1.0.0",
524
+ PreviousRequirements =
525
+ [
526
+ new ReportedRequirement()
527
+ {
528
+ Requirement = "1.0.0",
529
+ File = "/some-dir/project.csproj",
530
+ Groups = ["dependencies"],
531
+ }
532
+ ],
533
+ },
534
+ new ReportedDependency()
535
+ {
536
+ Name = "Some.Package2",
537
+ Version = "2.0.1",
538
+ Requirements =
539
+ [
540
+ new ReportedRequirement()
541
+ {
542
+ Requirement = "2.0.1",
543
+ File = "/some-dir/packages.config",
544
+ Groups = ["dependencies"],
545
+ Source = new()
546
+ {
547
+ SourceUrl = "https://nuget.example.com/some-package2",
548
+ Type = "nuget_repo",
549
+ }
550
+ }
551
+ ],
552
+ PreviousVersion = "2.0.0",
553
+ PreviousRequirements =
554
+ [
555
+ new ReportedRequirement()
556
+ {
557
+ Requirement = "2.0.0",
558
+ File = "/some-dir/packages.config",
559
+ Groups = ["dependencies"],
560
+ }
561
+ ],
562
+ },
563
+ ],
564
+ UpdatedDependencyFiles =
565
+ [
566
+ new DependencyFile()
567
+ {
568
+ Name = "project.csproj",
569
+ Directory = "/some-dir",
570
+ Content = """
571
+ <Project Sdk="Microsoft.NET.Sdk">
572
+ <PropertyGroup>
573
+ <TargetFramework>net8.0</TargetFramework>
574
+ </PropertyGroup>
575
+ <ItemGroup>
576
+ <PackageReference Include="Some.Package" Version="1.0.1" />
577
+ </ItemGroup>
578
+ <ItemGroup>
579
+ <Reference Include="Some.Package2">
580
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
581
+ <Private>True</Private>
582
+ </Reference>
583
+ </ItemGroup>
584
+ </Project>
585
+ """,
586
+ },
587
+ new DependencyFile()
588
+ {
589
+ Name = "packages.config",
590
+ Directory = "/some-dir",
591
+ Content = """
592
+ <?xml version="1.0" encoding="utf-8"?>
593
+ <packages>
594
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
595
+ </packages>
596
+ """,
597
+ },
598
+ ],
599
+ BaseCommitSha = "TEST-COMMIT-SHA",
600
+ CommitMessage = "TODO: message",
601
+ PrTitle = "TODO: title",
602
+ PrBody = "TODO: body",
603
+ },
604
+ new MarkAsProcessed("TEST-COMMIT-SHA")
605
+ ]
606
+ );
607
+ }
608
+
609
+ [Fact]
610
+ public async Task UpdateHandlesPackagesConfigFromReferencedCsprojFiles()
611
+ {
612
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
613
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
614
+ await RunAsync(
615
+ packages:
616
+ [
617
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", additionalMetadata: [repoMetadata]),
618
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net8.0", additionalMetadata: [repoMetadata]),
619
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "2.0.0", "net8.0", additionalMetadata: [repoMetadata2]),
620
+ MockNuGetPackage.CreateSimplePackage("Some.Package2", "2.0.1", "net8.0", additionalMetadata: [repoMetadata2]),
621
+ ],
622
+ job: new Job()
623
+ {
624
+ PackageManager = "nuget",
625
+ Source = new()
626
+ {
627
+ Provider = "github",
628
+ Repo = "test/repo",
629
+ Directory = "some-dir/ProjectA",
630
+ },
631
+ AllowedUpdates =
632
+ [
633
+ new() { UpdateType = "all" }
634
+ ]
635
+ },
636
+ files:
637
+ [
638
+ ("some-dir/ProjectA/ProjectA.csproj", """
639
+ <Project Sdk="Microsoft.NET.Sdk">
640
+ <PropertyGroup>
641
+ <TargetFramework>net8.0</TargetFramework>
642
+ </PropertyGroup>
643
+ <ItemGroup>
644
+ <PackageReference Include="Some.Package" Version="1.0.0" />
645
+ </ItemGroup>
646
+ <ItemGroup>
647
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
648
+ </ItemGroup>
649
+ </Project>
650
+ """),
651
+ ("some-dir/ProjectA/packages.config", """
652
+ <?xml version="1.0" encoding="utf-8"?>
653
+ <packages>
654
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
655
+ </packages>
656
+ """),
657
+ ("some-dir/ProjectB/ProjectB.csproj", """
658
+ <Project Sdk="Microsoft.NET.Sdk">
659
+ <PropertyGroup>
660
+ <TargetFramework>net8.0</TargetFramework>
661
+ </PropertyGroup>
662
+ <ItemGroup>
663
+ <PackageReference Include="Some.Package" Version="1.0.0" />
664
+ </ItemGroup>
665
+ </Project>
666
+ """),
667
+ ("some-dir/ProjectB/packages.config", """
668
+ <?xml version="1.0" encoding="utf-8"?>
669
+ <packages>
670
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
671
+ </packages>
672
+ """),
673
+ ],
674
+ discoveryWorker: new TestDiscoveryWorker(_input =>
675
+ {
676
+ return Task.FromResult(new WorkspaceDiscoveryResult()
677
+ {
678
+ Path = "some-dir/ProjectA",
679
+ Projects =
680
+ [
681
+ new()
682
+ {
683
+ FilePath = "../ProjectB/ProjectB.csproj",
684
+ TargetFrameworks = ["net8.0"],
685
+ Dependencies =
686
+ [
687
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
688
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
689
+ ]
690
+ },
691
+ new()
692
+ {
693
+ FilePath = "ProjectA.csproj",
694
+ TargetFrameworks = ["net8.0"],
695
+ Dependencies =
696
+ [
697
+ new("Some.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"]),
698
+ new("Some.Package2", "2.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net8.0"]),
699
+ ]
700
+ }
701
+ ]
702
+ });
703
+ }),
704
+ analyzeWorker: new TestAnalyzeWorker(input =>
705
+ {
706
+ var result = input.Item3.Name switch
707
+ {
708
+ "Some.Package" => new AnalysisResult()
709
+ {
710
+ CanUpdate = true,
711
+ UpdatedVersion = "1.0.1",
712
+ UpdatedDependencies =
713
+ [
714
+ new("Some.Package", "1.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package"),
715
+ ]
716
+ },
717
+ "Some.Package2" => new AnalysisResult()
718
+ {
719
+ CanUpdate = true,
720
+ UpdatedVersion = "2.0.1",
721
+ UpdatedDependencies =
722
+ [
723
+ new("Some.Package2", "2.0.1", DependencyType.Unknown, TargetFrameworks: ["net8.0"], InfoUrl: "https://nuget.example.com/some-package2"),
724
+ ]
725
+ },
726
+ _ => throw new NotSupportedException(),
727
+ };
728
+ return Task.FromResult(result);
729
+ }),
730
+ updaterWorker: new TestUpdaterWorker(async input =>
731
+ {
732
+ var repoRootPath = input.Item1;
733
+ var filePath = input.Item2;
734
+ var packageName = input.Item3;
735
+ var previousVersion = input.Item4;
736
+ var newVersion = input.Item5;
737
+ var _isTransitive = input.Item6;
738
+
739
+ var projectPath = Path.Join(repoRootPath, filePath);
740
+ var projectName = Path.GetFileName(projectPath);
741
+ var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath)!, "packages.config");
742
+ switch ((projectName, packageName))
743
+ {
744
+ case ("ProjectA.csproj", "Some.Package"):
745
+ await File.WriteAllTextAsync(projectPath, """
746
+ <Project Sdk="Microsoft.NET.Sdk">
747
+ <PropertyGroup>
748
+ <TargetFramework>net8.0</TargetFramework>
749
+ </PropertyGroup>
750
+ <ItemGroup>
751
+ <PackageReference Include="Some.Package" Version="1.0.1" />
752
+ </ItemGroup>
753
+ <ItemGroup>
754
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
755
+ </ItemGroup>
756
+ </Project>
757
+ """);
758
+ break;
759
+ case ("ProjectA.csproj", "Some.Package2"):
760
+ await File.WriteAllTextAsync(projectPath, """
761
+ <Project Sdk="Microsoft.NET.Sdk">
762
+ <PropertyGroup>
763
+ <TargetFramework>net8.0</TargetFramework>
764
+ </PropertyGroup>
765
+ <ItemGroup>
766
+ <PackageReference Include="Some.Package" Version="1.0.1" />
767
+ </ItemGroup>
768
+ <ItemGroup>
769
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
770
+ </ItemGroup>
771
+ <ItemGroup>
772
+ <Reference Include="Some.Package2">
773
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
774
+ <Private>True</Private>
775
+ </Reference>
776
+ </ItemGroup>
777
+ </Project>
778
+ """);
779
+ await File.WriteAllTextAsync(packagesConfigPath, """
780
+ <?xml version="1.0" encoding="utf-8"?>
781
+ <packages>
782
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
783
+ </packages>
784
+ """);
785
+ break;
786
+ case ("ProjectB.csproj", "Some.Package"):
787
+ await File.WriteAllTextAsync(projectPath, """
788
+ <Project Sdk="Microsoft.NET.Sdk">
789
+ <PropertyGroup>
790
+ <TargetFramework>net8.0</TargetFramework>
791
+ </PropertyGroup>
792
+ <ItemGroup>
793
+ <PackageReference Include="Some.Package" Version="1.0.1" />
794
+ </ItemGroup>
795
+ </Project>
796
+ """);
797
+ break;
798
+ case ("ProjectB.csproj", "Some.Package2"):
799
+ await File.WriteAllTextAsync(projectPath, """
800
+ <Project Sdk="Microsoft.NET.Sdk">
801
+ <PropertyGroup>
802
+ <TargetFramework>net8.0</TargetFramework>
803
+ </PropertyGroup>
804
+ <ItemGroup>
805
+ <PackageReference Include="Some.Package" Version="1.0.1" />
806
+ </ItemGroup>
807
+ <ItemGroup>
808
+ <Reference Include="Some.Package2">
809
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
810
+ <Private>True</Private>
811
+ </Reference>
812
+ </ItemGroup>
813
+ </Project>
814
+ """);
815
+ await File.WriteAllTextAsync(packagesConfigPath, """
816
+ <?xml version="1.0" encoding="utf-8"?>
817
+ <packages>
818
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
819
+ </packages>
820
+ """);
821
+ break;
822
+ default:
823
+ throw new NotSupportedException();
824
+ }
825
+
826
+ return new UpdateOperationResult();
827
+ }),
828
+ expectedResult: new RunResult()
829
+ {
830
+ Base64DependencyFiles =
831
+ [
832
+ new DependencyFile()
833
+ {
834
+ Directory = "/some-dir/ProjectB",
835
+ Name = "ProjectB.csproj",
836
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
837
+ <Project Sdk="Microsoft.NET.Sdk">
838
+ <PropertyGroup>
839
+ <TargetFramework>net8.0</TargetFramework>
840
+ </PropertyGroup>
841
+ <ItemGroup>
842
+ <PackageReference Include="Some.Package" Version="1.0.0" />
843
+ </ItemGroup>
844
+ </Project>
845
+ """))
846
+ },
847
+ new DependencyFile()
848
+ {
849
+ Directory = "/some-dir/ProjectB",
850
+ Name = "packages.config",
851
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
852
+ <?xml version="1.0" encoding="utf-8"?>
853
+ <packages>
854
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
855
+ </packages>
856
+ """))
857
+ },
858
+ new DependencyFile()
859
+ {
860
+ Directory = "/some-dir/ProjectA",
861
+ Name = "ProjectA.csproj",
862
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
863
+ <Project Sdk="Microsoft.NET.Sdk">
864
+ <PropertyGroup>
865
+ <TargetFramework>net8.0</TargetFramework>
866
+ </PropertyGroup>
867
+ <ItemGroup>
868
+ <PackageReference Include="Some.Package" Version="1.0.0" />
869
+ </ItemGroup>
870
+ <ItemGroup>
871
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
872
+ </ItemGroup>
873
+ </Project>
874
+ """))
875
+ },
876
+ new DependencyFile()
877
+ {
878
+ Directory = "/some-dir/ProjectA",
879
+ Name = "packages.config",
880
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
881
+ <?xml version="1.0" encoding="utf-8"?>
882
+ <packages>
883
+ <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
884
+ </packages>
885
+ """))
886
+ },
887
+ ],
888
+ BaseCommitSha = "TEST-COMMIT-SHA",
889
+ },
890
+ expectedApiMessages:
891
+ [
892
+ new UpdatedDependencyList()
893
+ {
894
+ Dependencies =
895
+ [
896
+ new ReportedDependency()
897
+ {
898
+ Name = "Some.Package",
899
+ Version = "1.0.0",
900
+ Requirements =
901
+ [
902
+ new ReportedRequirement()
903
+ {
904
+ Requirement = "1.0.0",
905
+ File = "/some-dir/ProjectB/ProjectB.csproj",
906
+ Groups = ["dependencies"],
907
+ }
908
+ ]
909
+ },
910
+ new ReportedDependency()
911
+ {
912
+ Name = "Some.Package2",
913
+ Version = "2.0.0",
914
+ Requirements =
915
+ [
916
+ new ReportedRequirement()
917
+ {
918
+ Requirement = "2.0.0",
919
+ File = "/some-dir/ProjectB/packages.config",
920
+ Groups = ["dependencies"],
921
+ }
922
+ ]
923
+ },
924
+ new ReportedDependency()
925
+ {
926
+ Name = "Some.Package",
927
+ Version = "1.0.0",
928
+ Requirements =
929
+ [
930
+ new ReportedRequirement()
931
+ {
932
+ Requirement = "1.0.0",
933
+ File = "/some-dir/ProjectA/ProjectA.csproj",
934
+ Groups = ["dependencies"],
935
+ }
936
+ ]
937
+ },
938
+ new ReportedDependency()
939
+ {
940
+ Name = "Some.Package2",
941
+ Version = "2.0.0",
942
+ Requirements =
943
+ [
944
+ new ReportedRequirement()
945
+ {
946
+ Requirement = "2.0.0",
947
+ File = "/some-dir/ProjectA/packages.config",
948
+ Groups = ["dependencies"],
949
+ }
950
+ ]
951
+ },
952
+ ],
953
+ DependencyFiles = ["/some-dir/ProjectB/ProjectB.csproj", "/some-dir/ProjectA/ProjectA.csproj", "/some-dir/ProjectB/packages.config", "/some-dir/ProjectA/packages.config"],
954
+ },
955
+ new IncrementMetric()
956
+ {
957
+ Metric = "updater.started",
958
+ Tags = new()
959
+ {
960
+ ["operation"] = "group_update_all_versions"
961
+ }
962
+ },
963
+ new CreatePullRequest()
964
+ {
965
+ Dependencies =
966
+ [
967
+ new ReportedDependency()
968
+ {
969
+ Name = "Some.Package",
970
+ Version = "1.0.1",
971
+ Requirements =
972
+ [
973
+ new ReportedRequirement()
974
+ {
975
+ Requirement = "1.0.1",
976
+ File = "/some-dir/ProjectB/ProjectB.csproj",
977
+ Groups = ["dependencies"],
978
+ Source = new()
979
+ {
980
+ SourceUrl = "https://nuget.example.com/some-package",
981
+ Type = "nuget_repo",
982
+ }
983
+ }
984
+ ],
985
+ PreviousVersion = "1.0.0",
986
+ PreviousRequirements =
987
+ [
988
+ new ReportedRequirement()
989
+ {
990
+ Requirement = "1.0.0",
991
+ File = "/some-dir/ProjectB/ProjectB.csproj",
992
+ Groups = ["dependencies"],
993
+ }
994
+ ],
995
+ },
996
+ new ReportedDependency()
997
+ {
998
+ Name = "Some.Package2",
999
+ Version = "2.0.1",
1000
+ Requirements =
1001
+ [
1002
+ new ReportedRequirement()
1003
+ {
1004
+ Requirement = "2.0.1",
1005
+ File = "/some-dir/ProjectB/packages.config",
1006
+ Groups = ["dependencies"],
1007
+ Source = new()
1008
+ {
1009
+ SourceUrl = "https://nuget.example.com/some-package2",
1010
+ Type = "nuget_repo",
1011
+ }
1012
+ }
1013
+ ],
1014
+ PreviousVersion = "2.0.0",
1015
+ PreviousRequirements =
1016
+ [
1017
+ new ReportedRequirement()
1018
+ {
1019
+ Requirement = "2.0.0",
1020
+ File = "/some-dir/ProjectB/packages.config",
1021
+ Groups = ["dependencies"],
1022
+ }
1023
+ ],
1024
+ },
1025
+ new ReportedDependency()
1026
+ {
1027
+ Name = "Some.Package",
1028
+ Version = "1.0.1",
1029
+ Requirements =
1030
+ [
1031
+ new ReportedRequirement()
1032
+ {
1033
+ Requirement = "1.0.1",
1034
+ File = "/some-dir/ProjectA/ProjectA.csproj",
1035
+ Groups = ["dependencies"],
1036
+ Source = new()
1037
+ {
1038
+ SourceUrl = "https://nuget.example.com/some-package",
1039
+ Type = "nuget_repo",
1040
+ }
1041
+ }
1042
+ ],
1043
+ PreviousVersion = "1.0.0",
1044
+ PreviousRequirements =
1045
+ [
1046
+ new ReportedRequirement()
1047
+ {
1048
+ Requirement = "1.0.0",
1049
+ File = "/some-dir/ProjectA/ProjectA.csproj",
1050
+ Groups = ["dependencies"],
1051
+ }
1052
+ ],
1053
+ },
1054
+ new ReportedDependency()
1055
+ {
1056
+ Name = "Some.Package2",
1057
+ Version = "2.0.1",
1058
+ Requirements =
1059
+ [
1060
+ new ReportedRequirement()
1061
+ {
1062
+ Requirement = "2.0.1",
1063
+ File = "/some-dir/ProjectA/packages.config",
1064
+ Groups = ["dependencies"],
1065
+ Source = new()
1066
+ {
1067
+ SourceUrl = "https://nuget.example.com/some-package2",
1068
+ Type = "nuget_repo",
1069
+ }
1070
+ }
1071
+ ],
1072
+ PreviousVersion = "2.0.0",
1073
+ PreviousRequirements =
1074
+ [
1075
+ new ReportedRequirement()
1076
+ {
1077
+ Requirement = "2.0.0",
1078
+ File = "/some-dir/ProjectA/packages.config",
1079
+ Groups = ["dependencies"],
1080
+ }
1081
+ ],
1082
+ },
1083
+ ],
1084
+ UpdatedDependencyFiles =
1085
+ [
1086
+ new DependencyFile()
1087
+ {
1088
+ Name = "ProjectB.csproj",
1089
+ Directory = "/some-dir/ProjectB",
1090
+ Content = """
1091
+ <Project Sdk="Microsoft.NET.Sdk">
1092
+ <PropertyGroup>
1093
+ <TargetFramework>net8.0</TargetFramework>
1094
+ </PropertyGroup>
1095
+ <ItemGroup>
1096
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1097
+ </ItemGroup>
1098
+ <ItemGroup>
1099
+ <Reference Include="Some.Package2">
1100
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
1101
+ <Private>True</Private>
1102
+ </Reference>
1103
+ </ItemGroup>
1104
+ </Project>
1105
+ """,
1106
+ },
1107
+ new DependencyFile()
1108
+ {
1109
+ Name = "packages.config",
1110
+ Directory = "/some-dir/ProjectB",
1111
+ Content = """
1112
+ <?xml version="1.0" encoding="utf-8"?>
1113
+ <packages>
1114
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1115
+ </packages>
1116
+ """,
1117
+ },
1118
+ new DependencyFile()
1119
+ {
1120
+ Name = "ProjectA.csproj",
1121
+ Directory = "/some-dir/ProjectA",
1122
+ Content = """
1123
+ <Project Sdk="Microsoft.NET.Sdk">
1124
+ <PropertyGroup>
1125
+ <TargetFramework>net8.0</TargetFramework>
1126
+ </PropertyGroup>
1127
+ <ItemGroup>
1128
+ <PackageReference Include="Some.Package" Version="1.0.1" />
1129
+ </ItemGroup>
1130
+ <ItemGroup>
1131
+ <ProjectReference Include="../ProjectB/ProjectB.csproj" />
1132
+ </ItemGroup>
1133
+ <ItemGroup>
1134
+ <Reference Include="Some.Package2">
1135
+ <HintPath>..\packages\Some.Package2.2.0.1\lib\net8.0\Some.Package2.dll</HintPath>
1136
+ <Private>True</Private>
1137
+ </Reference>
1138
+ </ItemGroup>
1139
+ </Project>
1140
+ """,
1141
+ },
1142
+ new DependencyFile()
1143
+ {
1144
+ Name = "packages.config",
1145
+ Directory = "/some-dir/ProjectA",
1146
+ Content = """
1147
+ <?xml version="1.0" encoding="utf-8"?>
1148
+ <packages>
1149
+ <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1150
+ </packages>
1151
+ """,
1152
+ },
1153
+ ],
1154
+ BaseCommitSha = "TEST-COMMIT-SHA",
1155
+ CommitMessage = "TODO: message",
1156
+ PrTitle = "TODO: title",
1157
+ PrBody = "TODO: body",
1158
+ },
1159
+ new MarkAsProcessed("TEST-COMMIT-SHA")
1160
+ ]
1161
+ );
1162
+ }
1163
+
1164
+ 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)
1165
+ {
1166
+ // arrange
1167
+ using var tempDirectory = new TemporaryDirectory();
1168
+ repoContentsPath ??= tempDirectory.DirectoryPath;
1169
+ await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, repoContentsPath);
1170
+ foreach (var (path, content) in files)
1171
+ {
1172
+ var fullPath = Path.Combine(repoContentsPath, path);
1173
+ var directory = Path.GetDirectoryName(fullPath)!;
1174
+ Directory.CreateDirectory(directory);
1175
+ await File.WriteAllTextAsync(fullPath, content);
1176
+ }
1177
+
1178
+ // act
1179
+ experimentsManager ??= new ExperimentsManager();
1180
+ var testApiHandler = new TestApiHandler();
1181
+ var logger = new TestLogger();
1182
+ discoveryWorker ??= new DiscoveryWorker(logger);
1183
+ analyzeWorker ??= new AnalyzeWorker(logger);
1184
+ updaterWorker ??= new UpdaterWorker(experimentsManager, logger);
1185
+
1186
+ var worker = new RunWorker(testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);
1187
+ var repoContentsPathDirectoryInfo = new DirectoryInfo(tempDirectory.DirectoryPath);
1188
+ var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA");
271
1189
  var actualApiMessages = testApiHandler.ReceivedMessages.ToArray();
272
1190
 
273
1191
  // assert