dependabot-nuget 0.284.0 → 0.286.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 (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