dependabot-nuget 0.268.0 → 0.270.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -479,7 +479,11 @@ public class MSBuildHelperTests : TestBase
479
479
  new Dependency("Some.Package", "1.2.0", DependencyType.PackageReference),
480
480
  new Dependency("Some.Other.Package", "1.0.0", DependencyType.PackageReference),
481
481
  };
482
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, new Logger(true));
482
+ var update = new[]
483
+ {
484
+ new Dependency("Some.Other.Package", "1.2.0", DependencyType.PackageReference),
485
+ };
486
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
483
487
  Assert.NotNull(resolvedDependencies);
484
488
  Assert.Equal(2, resolvedDependencies.Length);
485
489
  Assert.Equal("Some.Package", resolvedDependencies[0].Name);
@@ -493,6 +497,786 @@ public class MSBuildHelperTests : TestBase
493
497
  }
494
498
  }
495
499
 
500
+ #region
501
+ // Updating root package
502
+ // CS-Script Code to 2.0.0 requires its dependency Microsoft.CodeAnalysis.CSharp.Scripting to be 3.6.0 and its transitive dependency Microsoft.CodeAnalysis.Common to be 3.6.0
503
+ [Fact]
504
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingTopLevelPackage()
505
+ {
506
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewUpdatingTopLevelPackage)}_");
507
+
508
+ try
509
+ {
510
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
511
+ await File.WriteAllTextAsync(projectPath, """
512
+ <Project Sdk="Microsoft.NET.Sdk">
513
+ <PropertyGroup>
514
+ <TargetFramework>net8.0</TargetFramework>
515
+ </PropertyGroup>
516
+ <ItemGroup>
517
+ <PackageReference Include="CS-Script.Core" Version="1.3.1" />
518
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.4.0" />
519
+ <PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="3.4.0" />
520
+ </ItemGroup>
521
+ </Project>
522
+ """);
523
+
524
+ var dependencies = new[]
525
+ {
526
+ // Add comment about root and dependencies
527
+ new Dependency("CS-Script.Core", "1.3.1", DependencyType.PackageReference),
528
+ new Dependency("Microsoft.CodeAnalysis.Common", "3.4.0", DependencyType.PackageReference),
529
+ new Dependency("Microsoft.CodeAnalysis.Scripting.Common", "3.4.0", DependencyType.PackageReference),
530
+ };
531
+ var update = new[]
532
+ {
533
+ new Dependency("CS-Script.Core", "2.0.0", DependencyType.PackageReference),
534
+ };
535
+
536
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
537
+ Assert.NotNull(resolvedDependencies);
538
+ Assert.Equal(3, resolvedDependencies.Length);
539
+ Assert.Equal("CS-Script.Core", resolvedDependencies[0].Name);
540
+ Assert.Equal("2.0.0", resolvedDependencies[0].Version);
541
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[1].Name);
542
+ Assert.Equal("3.6.0", resolvedDependencies[1].Version);
543
+ Assert.Equal("Microsoft.CodeAnalysis.Scripting.Common", resolvedDependencies[2].Name);
544
+ Assert.Equal("3.6.0", resolvedDependencies[2].Version);
545
+ }
546
+ finally
547
+ {
548
+ repoRoot.Delete(recursive: true);
549
+ }
550
+ }
551
+
552
+ // Updating a dependency (Microsoft.Bcl.AsyncInterfaces) of the root package (Azure.Core) will require the root package to also update, but since the dependency is not in the existing list, we do not include it
553
+ [Fact]
554
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingNonExistingDependency()
555
+ {
556
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewUpdatingNonExistingDependency)}_");
557
+
558
+ try
559
+ {
560
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
561
+ await File.WriteAllTextAsync(projectPath, """
562
+ <Project Sdk="Microsoft.NET.Sdk">
563
+ <PropertyGroup>
564
+ <TargetFramework>net8.0</TargetFramework>
565
+ </PropertyGroup>
566
+ <ItemGroup>
567
+ <PackageReference Include="Azure.Core" Version="1.21.0" />
568
+ </ItemGroup>
569
+ </Project>
570
+ """);
571
+
572
+ var dependencies = new[]
573
+ {
574
+ new Dependency("Azure.Core", "1.21.0", DependencyType.PackageReference)
575
+ };
576
+ var update = new[]
577
+ {
578
+ new Dependency("Microsoft.Bcl.AsyncInterfaces", "1.1.1", DependencyType.Unknown)
579
+ };
580
+
581
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
582
+ Assert.NotNull(resolvedDependencies);
583
+ Assert.Single(resolvedDependencies);
584
+ Assert.Equal("Azure.Core", resolvedDependencies[0].Name);
585
+ Assert.Equal("1.22.0", resolvedDependencies[0].Version);
586
+ }
587
+ finally
588
+ {
589
+ repoRoot.Delete(recursive: true);
590
+ }
591
+ }
592
+
593
+ // Adding a reference
594
+ // Newtonsoft.Json needs to update to 13.0.1. Although Newtonsoft.Json.Bson can use the original version of 12.0.1, for security vulnerabilities and
595
+ // because there is no later version of Newtonsoft.Json.Bson 1.0.2, Newtonsoft.Json would be added to the existing list to prevent resolution
596
+ [Fact]
597
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingNonExistentDependencyAndKeepingReference()
598
+ {
599
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewUpdatingNonExistentDependencyAndKeepingReference)}_");
600
+
601
+ try
602
+ {
603
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
604
+ await File.WriteAllTextAsync(projectPath, """
605
+ <Project Sdk="Microsoft.NET.Sdk">
606
+ <PropertyGroup>
607
+ <TargetFramework>net8.0</TargetFramework>
608
+ </PropertyGroup>
609
+ <ItemGroup>
610
+ <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
611
+ </ItemGroup>
612
+ </Project>
613
+ """);
614
+
615
+ var dependencies = new[]
616
+ {
617
+ new Dependency("Newtonsoft.Json.Bson", "1.0.2", DependencyType.PackageReference)
618
+ };
619
+ var update = new[]
620
+ {
621
+ new Dependency("Newtonsoft.Json", "13.0.1", DependencyType.Unknown)
622
+ };
623
+
624
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
625
+ Assert.NotNull(resolvedDependencies);
626
+ Assert.Equal(2, resolvedDependencies.Length);
627
+ Assert.Equal("Newtonsoft.Json.Bson", resolvedDependencies[0].Name);
628
+ Assert.Equal("1.0.2", resolvedDependencies[0].Version);
629
+ Assert.Equal("Newtonsoft.Json", resolvedDependencies[1].Name);
630
+ Assert.Equal("13.0.1", resolvedDependencies[1].Version);
631
+ }
632
+ finally
633
+ {
634
+ repoRoot.Delete(recursive: true);
635
+ }
636
+ }
637
+
638
+ // Updating unreferenced dependency
639
+ // Root package (Microsoft.CodeAnalysis.Compilers) and its dependencies (Microsoft.CodeAnalysis.CSharp), (Microsoft.CodeAnalysis.VisualBasic) are all 4.9.2
640
+ // These packages all require the transitive dependency of the root package (Microsoft.CodeAnalysis.Common) to be 4.9.2, but it's not in the existing list
641
+ // If Microsoft.CodeAnalysis.Common is updated to 4.10.0, everything else updates and Microsoft.CoseAnalysis.Common is not kept in the existing list
642
+ [Fact]
643
+ public async Task DependencyConflictsCanBeResolvedNewTransitiveDependencyNotExisting()
644
+ {
645
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewTransitiveDependencyNotExisting)}_");
646
+
647
+ try
648
+ {
649
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
650
+ await File.WriteAllTextAsync(projectPath, """
651
+ <Project Sdk="Microsoft.NET.Sdk">
652
+ <PropertyGroup>
653
+ <TargetFramework>net8.0</TargetFramework>
654
+ </PropertyGroup>
655
+ <ItemGroup>
656
+ <PackageReference Include="Microsoft.CodeAnalysis.Compilers" Version="4.9.2" />
657
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
658
+ <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.9.2" />
659
+ </ItemGroup>
660
+ </Project>
661
+ """);
662
+
663
+ var dependencies = new[]
664
+ {
665
+ new Dependency("Microsoft.CodeAnalysis.Compilers", "4.9.2", DependencyType.PackageReference),
666
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "4.9.2", DependencyType.PackageReference),
667
+ new Dependency("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", DependencyType.PackageReference)
668
+ };
669
+ var update = new[]
670
+ {
671
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference)
672
+ };
673
+
674
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
675
+ Assert.NotNull(resolvedDependencies);
676
+ Assert.Equal(3, resolvedDependencies.Length);
677
+ Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
678
+ Assert.Equal("4.10.0", resolvedDependencies[0].Version);
679
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[1].Name);
680
+ Assert.Equal("4.10.0", resolvedDependencies[1].Version);
681
+ Assert.Equal("Microsoft.CodeAnalysis.VisualBasic", resolvedDependencies[2].Name);
682
+ Assert.Equal("4.10.0", resolvedDependencies[2].Version);
683
+ }
684
+ finally
685
+ {
686
+ repoRoot.Delete(recursive: true);
687
+ }
688
+ }
689
+
690
+ // Updating referenced dependency
691
+ // The same as previous test, but the transitive dependency (Microsoft.CodeAnalysis.Common) is in the existing list
692
+ [Fact]
693
+ public async Task DependencyConflictsCanBeResolvedNewSingleTransitiveDependencyExisting()
694
+ {
695
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewSingleTransitiveDependencyExisting)}_");
696
+
697
+ try
698
+ {
699
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
700
+ await File.WriteAllTextAsync(projectPath, """
701
+ <Project Sdk="Microsoft.NET.Sdk">
702
+ <PropertyGroup>
703
+ <TargetFramework>net8.0</TargetFramework>
704
+ </PropertyGroup>
705
+ <ItemGroup>
706
+ <PackageReference Include="Microsoft.CodeAnalysis.Compilers" Version="4.9.2" />
707
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" />
708
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
709
+ <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.9.2" />
710
+ </ItemGroup>
711
+ </Project>
712
+ """);
713
+
714
+ var dependencies = new[]
715
+ {
716
+ new Dependency("Microsoft.CodeAnalysis.Compilers", "4.9.2", DependencyType.PackageReference),
717
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.9.2", DependencyType.PackageReference),
718
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "4.9.2", DependencyType.PackageReference),
719
+ new Dependency("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", DependencyType.PackageReference)
720
+ };
721
+ var update = new[]
722
+ {
723
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference)
724
+ };
725
+
726
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
727
+ Assert.NotNull(resolvedDependencies);
728
+ Assert.Equal(4, resolvedDependencies.Length);
729
+ Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
730
+ Assert.Equal("4.10.0", resolvedDependencies[0].Version);
731
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[1].Name);
732
+ Assert.Equal("4.10.0", resolvedDependencies[1].Version);
733
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[2].Name);
734
+ Assert.Equal("4.10.0", resolvedDependencies[2].Version);
735
+ Assert.Equal("Microsoft.CodeAnalysis.VisualBasic", resolvedDependencies[3].Name);
736
+ Assert.Equal("4.10.0", resolvedDependencies[3].Version);
737
+ }
738
+ finally
739
+ {
740
+ repoRoot.Delete(recursive: true);
741
+ }
742
+ }
743
+
744
+ // A combination of the third and fourth test, to measure efficiency of updating separate families
745
+ // Keeping a dependency that was not included in the original list (Newtonsoft.Json)
746
+ // Not keeping a dependency that was not included in the original list (Microsoft.CodeAnalysis.Common)
747
+ [Fact]
748
+ public async Task DependencyConflictsCanBeResolvedNewSelectiveAdditionPackages()
749
+ {
750
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewSelectiveAdditionPackages)}_");
751
+
752
+ try
753
+ {
754
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
755
+ await File.WriteAllTextAsync(projectPath, """
756
+ <Project Sdk="Microsoft.NET.Sdk">
757
+ <PropertyGroup>
758
+ <TargetFramework>net8.0</TargetFramework>
759
+ </PropertyGroup>
760
+ <ItemGroup>
761
+ <PackageReference Include="Microsoft.CodeAnalysis.Compilers" Version="4.9.2" />
762
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
763
+ <PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.9.2" />
764
+ <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
765
+ </ItemGroup>
766
+ </Project>
767
+ """);
768
+
769
+ var dependencies = new[]
770
+ {
771
+ new Dependency("Microsoft.CodeAnalysis.Compilers", "4.9.2", DependencyType.PackageReference),
772
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "4.9.2", DependencyType.PackageReference),
773
+ new Dependency("Microsoft.CodeAnalysis.VisualBasic", "4.9.2", DependencyType.PackageReference),
774
+ new Dependency("Newtonsoft.Json.Bson", "1.0.2", DependencyType.PackageReference)
775
+ };
776
+ var update = new[]
777
+ {
778
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference),
779
+ new Dependency("Newtonsoft.Json", "13.0.1", DependencyType.Unknown)
780
+ };
781
+
782
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
783
+ Assert.NotNull(resolvedDependencies);
784
+ Assert.Equal(5, resolvedDependencies.Length);
785
+ Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
786
+ Assert.Equal("4.10.0", resolvedDependencies[0].Version);
787
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[1].Name);
788
+ Assert.Equal("4.10.0", resolvedDependencies[1].Version);
789
+ Assert.Equal("Microsoft.CodeAnalysis.VisualBasic", resolvedDependencies[2].Name);
790
+ Assert.Equal("4.10.0", resolvedDependencies[2].Version);
791
+ Assert.Equal("Newtonsoft.Json.Bson", resolvedDependencies[3].Name);
792
+ Assert.Equal("1.0.2", resolvedDependencies[3].Version);
793
+ Assert.Equal("Newtonsoft.Json", resolvedDependencies[4].Name);
794
+ Assert.Equal("13.0.1", resolvedDependencies[4].Version);
795
+ }
796
+ finally
797
+ {
798
+ repoRoot.Delete(recursive: true);
799
+ }
800
+ }
801
+
802
+ // Two top level packages (Buildalyzer), (Microsoft.CodeAnalysis.CSharp.Scripting) that share a dependency (Microsoft.CodeAnalysis.Csharp)
803
+ // Updating ONE of the top level packages, which updates the dependencies and their other "parents"
804
+ // First family: Buildalyzer 7.0.1 requires Microsoft.CodeAnalysis.CSharp to be >= 4.0.0 and Microsoft.CodeAnalysis.Common to be 4.0.0 (@ 6.0.4, Microsoft.CodeAnalysis.Common isn't a dependency of buildalyzer)
805
+ // Second family: Microsoft.CodeAnalysis.CSharp.Scripting 4.0.0 requires Microsoft.CodeAnalysis.CSharp 4.0.0 and Microsoft.CodeAnalysis.Common to be 4.0.0 (Specific version)
806
+ // Updating Buildalyzer to 7.0.1 will update its transitive dependency (Microsoft.CodeAnalysis.Common) and then its transitive dependency's "family"
807
+ [Fact]
808
+ public async Task DependencyConflictsCanBeResolvedNewSharingDependency()
809
+ {
810
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewSharingDependency)}_");
811
+
812
+ try
813
+ {
814
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
815
+ await File.WriteAllTextAsync(projectPath, """
816
+ <Project Sdk="Microsoft.NET.Sdk">
817
+ <PropertyGroup>
818
+ <TargetFramework>net8.0</TargetFramework>
819
+ </PropertyGroup>
820
+ <ItemGroup>
821
+ <PackageReference Include="Buildalyzer" Version="6.0.4" />
822
+ <PackageReference Include="Microsoft.CodeAnalysis.Csharp.Scripting" Version="3.10.0" />
823
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
824
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" />
825
+ </ItemGroup>
826
+ </Project>
827
+ """);
828
+
829
+ var dependencies = new[]
830
+ {
831
+ new Dependency("Buildalyzer", "6.0.4", DependencyType.PackageReference),
832
+ new Dependency("Microsoft.CodeAnalysis.CSharp.Scripting", "3.10.0", DependencyType.PackageReference),
833
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "3.10.0", DependencyType.PackageReference),
834
+ new Dependency("Microsoft.CodeAnalysis.Common", "3.10.0", DependencyType.PackageReference),
835
+ };
836
+ var update = new[]
837
+ {
838
+ new Dependency("Buildalyzer", "7.0.1", DependencyType.PackageReference),
839
+ };
840
+
841
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
842
+ Assert.NotNull(resolvedDependencies);
843
+ Assert.Equal(4, resolvedDependencies.Length);
844
+ Assert.Equal("Buildalyzer", resolvedDependencies[0].Name);
845
+ Assert.Equal("7.0.1", resolvedDependencies[0].Version);
846
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp.Scripting", resolvedDependencies[1].Name);
847
+ Assert.Equal("4.0.0", resolvedDependencies[1].Version);
848
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[2].Name);
849
+ Assert.Equal("4.0.0", resolvedDependencies[2].Version);
850
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[3].Name);
851
+ Assert.Equal("4.0.0", resolvedDependencies[3].Version);
852
+ }
853
+ finally
854
+ {
855
+ repoRoot.Delete(recursive: true);
856
+ }
857
+ }
858
+
859
+ // Updating two families at once to test efficiency
860
+ // First family: Direct dependency (Microsoft.CodeAnalysis.Common) needs to be updated, which will then need to update in the existing list its dependency (System.Collections.Immutable) and "parent" (Microsoft.CodeAnalysis.Csharp.Scripting)
861
+ // Second family: Updating the root package (Azure.Core) in the existing list will also need to update its dependency (Microsoft.Bcl.AsyncInterfaces)
862
+ [Fact]
863
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingEntireFamily()
864
+ {
865
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewUpdatingEntireFamily)}_");
866
+
867
+ try
868
+ {
869
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
870
+ await File.WriteAllTextAsync(projectPath, """
871
+ <Project Sdk="Microsoft.NET.Sdk">
872
+ <PropertyGroup>
873
+ <TargetFramework>net8.0</TargetFramework>
874
+ </PropertyGroup>
875
+ <ItemGroup>
876
+ <PackageReference Include="System.Collections.Immutable" Version="7.0.0" />
877
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.8.0" />
878
+ <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0" />
879
+ <PackageReference Include="Azure.Core" Version="1.21.0" />
880
+ </ItemGroup>
881
+ </Project>
882
+ """);
883
+
884
+ var dependencies = new[]
885
+ {
886
+ new Dependency("System.Collections.Immutable", "7.0.0", DependencyType.PackageReference),
887
+ new Dependency("Microsoft.CodeAnalysis.CSharp.Scripting", "4.8.0", DependencyType.PackageReference),
888
+ new Dependency("Microsoft.Bcl.AsyncInterfaces", "1.0.0", DependencyType.Unknown),
889
+ new Dependency("Azure.Core", "1.21.0", DependencyType.PackageReference),
890
+
891
+ };
892
+ var update = new[]
893
+ {
894
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference),
895
+ new Dependency("Azure.Core", "1.22.0", DependencyType.PackageReference)
896
+ };
897
+
898
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
899
+ Assert.NotNull(resolvedDependencies);
900
+ Assert.Equal(4, resolvedDependencies.Length);
901
+ Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
902
+ Assert.Equal("8.0.0", resolvedDependencies[0].Version);
903
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp.Scripting", resolvedDependencies[1].Name);
904
+ Assert.Equal("4.10.0", resolvedDependencies[1].Version);
905
+ Assert.Equal("Microsoft.Bcl.AsyncInterfaces", resolvedDependencies[2].Name);
906
+ Assert.Equal("1.1.1", resolvedDependencies[2].Version);
907
+ Assert.Equal("Azure.Core", resolvedDependencies[3].Name);
908
+ Assert.Equal("1.22.0", resolvedDependencies[3].Version);
909
+ }
910
+ finally
911
+ {
912
+ repoRoot.Delete(recursive: true);
913
+ }
914
+ }
915
+
916
+ // Similar to the last test, except Microsoft.CodeAnalysis.Common is in the existing list
917
+ [Fact]
918
+ public async Task DependencyConflictsCanBeResolvedNewUpdatingTopLevelAndDependency()
919
+ {
920
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewUpdatingTopLevelAndDependency)}_");
921
+
922
+ try
923
+ {
924
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
925
+ await File.WriteAllTextAsync(projectPath, """
926
+ <Project Sdk="Microsoft.NET.Sdk">
927
+ <PropertyGroup>
928
+ <TargetFramework>net8.0</TargetFramework>
929
+ </PropertyGroup>
930
+ <ItemGroup>
931
+ <PackageReference Include="System.Collections.Immutable" Version="7.0.0" />
932
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.8.0" />
933
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
934
+ <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0" />
935
+ <PackageReference Include="Azure.Core" Version="1.21.0" />
936
+ </ItemGroup>
937
+ </Project>
938
+ """);
939
+
940
+ var dependencies = new[]
941
+ {
942
+ new Dependency("System.Collections.Immutable", "7.0.0", DependencyType.PackageReference),
943
+ new Dependency("Microsoft.CodeAnalysis.CSharp.Scripting", "4.8.0", DependencyType.PackageReference),
944
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.8.0", DependencyType.PackageReference),
945
+ new Dependency("Microsoft.Bcl.AsyncInterfaces", "1.0.0", DependencyType.Unknown),
946
+ new Dependency("Azure.Core", "1.21.0", DependencyType.PackageReference),
947
+
948
+ };
949
+ var update = new[]
950
+ {
951
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference),
952
+ new Dependency("Azure.Core", "1.22.0", DependencyType.PackageReference)
953
+ };
954
+
955
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
956
+ Assert.NotNull(resolvedDependencies);
957
+ Assert.Equal(5, resolvedDependencies.Length);
958
+ Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
959
+ Assert.Equal("8.0.0", resolvedDependencies[0].Version);
960
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp.Scripting", resolvedDependencies[1].Name);
961
+ Assert.Equal("4.10.0", resolvedDependencies[1].Version);
962
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[2].Name);
963
+ Assert.Equal("4.10.0", resolvedDependencies[2].Version);
964
+ Assert.Equal("Microsoft.Bcl.AsyncInterfaces", resolvedDependencies[3].Name);
965
+ Assert.Equal("1.1.1", resolvedDependencies[3].Version);
966
+ Assert.Equal("Azure.Core", resolvedDependencies[4].Name);
967
+ Assert.Equal("1.22.0", resolvedDependencies[4].Version);
968
+ }
969
+ finally
970
+ {
971
+ repoRoot.Delete(recursive: true);
972
+ }
973
+ }
974
+
975
+ // Out of scope test: AutoMapper.Extensions.Microsoft.DependencyInjection's versions are not yet compatible
976
+ // To update root package (AutoMapper.Collection) to 10.0.0, its dependency (AutoMapper) needs to update to 13.0.0.
977
+ // However, there is no higher version of AutoMapper's other "parent" (AutoMapper.Extensions.Microsoft.DependencyInjection) that is compatible with the new version
978
+ [Fact]
979
+ public async Task DependencyConflictsCanBeResolvedNewOutOfScope()
980
+ {
981
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewOutOfScope)}_");
982
+
983
+ try
984
+ {
985
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
986
+ await File.WriteAllTextAsync(projectPath, """
987
+ <Project Sdk="Microsoft.NET.Sdk">
988
+ <PropertyGroup>
989
+ <TargetFramework>net8.0</TargetFramework>
990
+ </PropertyGroup>
991
+ <ItemGroup>
992
+ <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
993
+ <PackageReference Include="AutoMapper" Version="12.0.1" />
994
+ <PackageReference Include="AutoMapper.Collection" Version="9.0.0" />
995
+ </ItemGroup>
996
+ </Project>
997
+ """);
998
+
999
+ var dependencies = new[]
1000
+ {
1001
+ new Dependency("AutoMapper.Extensions.Microsoft.DependencyInjection", "12.0.1", DependencyType.PackageReference),
1002
+ new Dependency("AutoMapper", "12.0.1", DependencyType.PackageReference),
1003
+ new Dependency("AutoMapper.Collection", "9.0.0", DependencyType.PackageReference)
1004
+ };
1005
+ var update = new[]
1006
+ {
1007
+ new Dependency("AutoMapper.Collection", "10.0.0", DependencyType.PackageReference)
1008
+ };
1009
+
1010
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1011
+ Assert.NotNull(resolvedDependencies);
1012
+ Assert.Equal(3, resolvedDependencies.Length);
1013
+ Assert.Equal("AutoMapper.Extensions.Microsoft.DependencyInjection", resolvedDependencies[0].Name);
1014
+ Assert.Equal("12.0.1", resolvedDependencies[0].Version);
1015
+ Assert.Equal("AutoMapper", resolvedDependencies[1].Name);
1016
+ Assert.Equal("12.0.1", resolvedDependencies[1].Version);
1017
+ Assert.Equal("AutoMapper.Collection", resolvedDependencies[2].Name);
1018
+ Assert.Equal("9.0.0", resolvedDependencies[2].Version);
1019
+ }
1020
+ finally
1021
+ {
1022
+ repoRoot.Delete(recursive: true);
1023
+ }
1024
+ }
1025
+
1026
+ // Two dependencies (Microsoft.Extensions.Caching.Memory), (Microsoft.EntityFrameworkCore.Analyzers) used by the same parent (Microsoft.EntityFrameworkCore), updating one of the dependencies
1027
+ [Fact]
1028
+ public async Task DependencyConflictsCanBeResolvedNewTwoDependenciesShareSameParent()
1029
+ {
1030
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewTwoDependenciesShareSameParent)}_");
1031
+
1032
+ try
1033
+ {
1034
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
1035
+ await File.WriteAllTextAsync(projectPath, """
1036
+ <Project Sdk="Microsoft.NET.Sdk">
1037
+ <PropertyGroup>
1038
+ <TargetFramework>net8.0</TargetFramework>
1039
+ </PropertyGroup>
1040
+ <ItemGroup>
1041
+ <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.11" />
1042
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="7.0.11" />
1043
+ </ItemGroup>
1044
+ </Project>
1045
+ """);
1046
+
1047
+ var dependencies = new[]
1048
+ {
1049
+ new Dependency("Microsoft.EntityFrameworkCore", "7.0.11", DependencyType.PackageReference),
1050
+ new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "7.0.11", DependencyType.PackageReference)
1051
+ };
1052
+ var update = new[]
1053
+ {
1054
+ new Dependency("Microsoft.Extensions.Caching.Memory", "8.0.0", DependencyType.PackageReference)
1055
+ };
1056
+
1057
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1058
+ Assert.NotNull(resolvedDependencies);
1059
+ Assert.Equal(2, resolvedDependencies.Length);
1060
+ Assert.Equal("Microsoft.EntityFrameworkCore", resolvedDependencies[0].Name);
1061
+ Assert.Equal("8.0.0", resolvedDependencies[0].Version);
1062
+ Assert.Equal("Microsoft.EntityFrameworkCore.Analyzers", resolvedDependencies[1].Name);
1063
+ Assert.Equal("8.0.0", resolvedDependencies[1].Version);
1064
+ }
1065
+ finally
1066
+ {
1067
+ repoRoot.Delete(recursive: true);
1068
+ }
1069
+ }
1070
+
1071
+ // Updating referenced package
1072
+ // 4 dependency chain to be updated. Since the package to be updated is in the existing list, do not update its parents since we want to change as little as possible
1073
+ [Fact]
1074
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourExisting()
1075
+ {
1076
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewFamilyOfFourExisting)}_");
1077
+
1078
+ try
1079
+ {
1080
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
1081
+ await File.WriteAllTextAsync(projectPath, """
1082
+ <Project Sdk="Microsoft.NET.Sdk">
1083
+ <PropertyGroup>
1084
+ <TargetFramework>net8.0</TargetFramework>
1085
+ </PropertyGroup>
1086
+ <ItemGroup>
1087
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0" />
1088
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0" />
1089
+ <PackageReference Include= "Microsoft.EntityFrameworkCore" Version="7.0.0" />
1090
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="7.0.0" />
1091
+ </ItemGroup>
1092
+ </Project>
1093
+ """);
1094
+
1095
+ var dependencies = new[]
1096
+ {
1097
+ new Dependency("Microsoft.EntityFrameworkCore.Design", "7.0.0", DependencyType.PackageReference),
1098
+ new Dependency("Microsoft.EntityFrameworkCore.Relational", "7.0.0", DependencyType.PackageReference),
1099
+ new Dependency("Microsoft.EntityFrameworkCore", "7.0.0", DependencyType.PackageReference),
1100
+ new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "7.0.0", DependencyType.PackageReference)
1101
+ };
1102
+ var update = new[]
1103
+ {
1104
+ new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", DependencyType.PackageReference)
1105
+ };
1106
+
1107
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1108
+ Assert.NotNull(resolvedDependencies);
1109
+ Assert.Equal(4, resolvedDependencies.Length);
1110
+ Assert.Equal("Microsoft.EntityFrameworkCore.Design", resolvedDependencies[0].Name);
1111
+ Assert.Equal("7.0.0", resolvedDependencies[0].Version);
1112
+ Assert.Equal("Microsoft.EntityFrameworkCore.Relational", resolvedDependencies[1].Name);
1113
+ Assert.Equal("7.0.0", resolvedDependencies[1].Version);
1114
+ Assert.Equal("Microsoft.EntityFrameworkCore", resolvedDependencies[2].Name);
1115
+ Assert.Equal("7.0.0", resolvedDependencies[2].Version);
1116
+ Assert.Equal("Microsoft.EntityFrameworkCore.Analyzers", resolvedDependencies[3].Name);
1117
+ Assert.Equal("8.0.0", resolvedDependencies[3].Version);
1118
+ }
1119
+ finally
1120
+ {
1121
+ repoRoot.Delete(recursive: true);
1122
+ }
1123
+ }
1124
+
1125
+ // Updating unreferenced package
1126
+ // 4 dependency chain to be updated, dependency to be updated is not in the existing list, so its family will all be updated
1127
+ [Fact]
1128
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourNotInExisting()
1129
+ {
1130
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewFamilyOfFourNotInExisting)}_");
1131
+
1132
+ try
1133
+ {
1134
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
1135
+ await File.WriteAllTextAsync(projectPath, """
1136
+ <Project Sdk="Microsoft.NET.Sdk">
1137
+ <PropertyGroup>
1138
+ <TargetFramework>net8.0</TargetFramework>
1139
+ </PropertyGroup>
1140
+ <ItemGroup>
1141
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0" />
1142
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0" />
1143
+ <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
1144
+ </ItemGroup>
1145
+ </Project>
1146
+ """);
1147
+
1148
+ var dependencies = new[]
1149
+ {
1150
+ new Dependency("Microsoft.EntityFrameworkCore.Design", "7.0.0", DependencyType.PackageReference),
1151
+ new Dependency("Microsoft.EntityFrameworkCore.Relational", "7.0.0", DependencyType.PackageReference),
1152
+ new Dependency("Microsoft.EntityFrameworkCore", "7.0.0", DependencyType.PackageReference),
1153
+ };
1154
+ var update = new[]
1155
+ {
1156
+ new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", DependencyType.PackageReference)
1157
+ };
1158
+
1159
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1160
+ Assert.NotNull(resolvedDependencies);
1161
+ Assert.Equal(3, resolvedDependencies.Length);
1162
+ Assert.Equal("Microsoft.EntityFrameworkCore.Design", resolvedDependencies[0].Name);
1163
+ Assert.Equal("8.0.0", resolvedDependencies[0].Version);
1164
+ Assert.Equal("Microsoft.EntityFrameworkCore.Relational", resolvedDependencies[1].Name);
1165
+ Assert.Equal("8.0.0", resolvedDependencies[1].Version);
1166
+ Assert.Equal("Microsoft.EntityFrameworkCore", resolvedDependencies[2].Name);
1167
+ Assert.Equal("8.0.0", resolvedDependencies[2].Version);
1168
+ }
1169
+ finally
1170
+ {
1171
+ repoRoot.Delete(recursive: true);
1172
+ }
1173
+ }
1174
+
1175
+ // Updating a referenced transitive dependency
1176
+ // Updating a transtitive dependency (System.Collections.Immutable) to 8.0.0, which will update its "parent" (Microsoft.CodeAnalysis.CSharp) and its "grandparent" (Microsoft.CodeAnalysis.CSharp.Workspaces) to update
1177
+ [Fact]
1178
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificExisting()
1179
+ {
1180
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificExisting)}_");
1181
+
1182
+ try
1183
+ {
1184
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
1185
+ await File.WriteAllTextAsync(projectPath, """
1186
+ <Project Sdk="Microsoft.NET.Sdk">
1187
+ <PropertyGroup>
1188
+ <TargetFramework>net8.0</TargetFramework>
1189
+ </PropertyGroup>
1190
+ <ItemGroup>
1191
+ <PackageReference Include="System.Collections.Immutable" Version="7.0.0" />
1192
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
1193
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
1194
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
1195
+ </ItemGroup>
1196
+ </Project>
1197
+ """);
1198
+
1199
+ var dependencies = new[]
1200
+ {
1201
+ new Dependency("System.Collections.Immutable", "7.0.0", DependencyType.PackageReference),
1202
+ new Dependency("Microsoft.CodeAnalysis.CSharp.Workspaces", "4.8.0", DependencyType.PackageReference),
1203
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "4.8.0", DependencyType.PackageReference),
1204
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.8.0", DependencyType.PackageReference),
1205
+ };
1206
+ var update = new[]
1207
+ {
1208
+ new Dependency("System.Collections.Immutable", "8.0.0", DependencyType.PackageReference),
1209
+ };
1210
+
1211
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1212
+ Assert.NotNull(resolvedDependencies);
1213
+ Assert.Equal(4, resolvedDependencies.Length);
1214
+ Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
1215
+ Assert.Equal("8.0.0", resolvedDependencies[0].Version);
1216
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp.Workspaces", resolvedDependencies[1].Name);
1217
+ Assert.Equal("4.8.0", resolvedDependencies[1].Version);
1218
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[2].Name);
1219
+ Assert.Equal("4.8.0", resolvedDependencies[2].Version);
1220
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[3].Name);
1221
+ Assert.Equal("4.8.0", resolvedDependencies[3].Version);
1222
+ }
1223
+ finally
1224
+ {
1225
+ repoRoot.Delete(recursive: true);
1226
+ }
1227
+ }
1228
+
1229
+ // Similar to the last test, with the "grandchild" (System.Collections.Immutable) not in the existing list
1230
+ [Fact]
1231
+ public async Task DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificNotInExisting()
1232
+ {
1233
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedNewFamilyOfFourSpecificNotInExisting)}_");
1234
+
1235
+ try
1236
+ {
1237
+ var projectPath = Path.Join(repoRoot.FullName, "project.csproj");
1238
+ await File.WriteAllTextAsync(projectPath, """
1239
+ <Project Sdk="Microsoft.NET.Sdk">
1240
+ <PropertyGroup>
1241
+ <TargetFramework>net8.0</TargetFramework>
1242
+ </PropertyGroup>
1243
+ <ItemGroup>
1244
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
1245
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
1246
+ <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
1247
+ </ItemGroup>
1248
+ </Project>
1249
+ """);
1250
+
1251
+ var dependencies = new[]
1252
+ {
1253
+ new Dependency("Microsoft.CodeAnalysis.CSharp.Workspaces", "4.8.0", DependencyType.PackageReference),
1254
+ new Dependency("Microsoft.CodeAnalysis.CSharp", "4.8.0", DependencyType.PackageReference),
1255
+ new Dependency("Microsoft.CodeAnalysis.Common", "4.8.0", DependencyType.PackageReference),
1256
+
1257
+ };
1258
+ var update = new[]
1259
+ {
1260
+ new Dependency("System.Collections.Immutable", "8.0.0", DependencyType.PackageReference),
1261
+ };
1262
+
1263
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new Logger(true));
1264
+ Assert.NotNull(resolvedDependencies);
1265
+ Assert.Equal(3, resolvedDependencies.Length);
1266
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp.Workspaces", resolvedDependencies[0].Name);
1267
+ Assert.Equal("4.9.2", resolvedDependencies[0].Version);
1268
+ Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[1].Name);
1269
+ Assert.Equal("4.9.2", resolvedDependencies[1].Version);
1270
+ Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[2].Name);
1271
+ Assert.Equal("4.9.2", resolvedDependencies[2].Version);
1272
+ }
1273
+ finally
1274
+ {
1275
+ repoRoot.Delete(recursive: true);
1276
+ }
1277
+ }
1278
+ #endregion
1279
+
496
1280
  public static IEnumerable<object[]> GetTopLevelPackageDependencyInfosTestData()
497
1281
  {
498
1282
  // simple case