diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs index c862d6cc93..61812f5b95 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs @@ -3075,14 +3075,14 @@ await TestUpdateForProject("Some.Package", "12.0.1", "13.0.1", public async Task UpdatingTransitiveDependencyWithNewSolverCanUpdateJustTheTopLevelPackage() { // we've been asked to explicitly update a transitive dependency, but we can solve it by updating the top-level package instead - await TestUpdateForProject("Transitive.Package", "1.0.0", "2.0.0", + await TestUpdateForProject("Transitive.Package", "7.0.0", "8.0.0", isTransitive: true, packages: [ - MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", [("net8.0", [("Transitive.Package", "[1.0.0]")])]), - MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0", [("net8.0", [("Transitive.Package", "[2.0.0]")])]), - MockNuGetPackage.CreateSimplePackage("Transitive.Package", "1.0.0", "net8.0"), - MockNuGetPackage.CreateSimplePackage("Transitive.Package", "2.0.0", "net8.0"), + MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", [("net8.0", [("Transitive.Package", "[7.0.0]")])]), + MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0", [("net8.0", [("Transitive.Package", "[8.0.0]")])]), + MockNuGetPackage.CreateSimplePackage("Transitive.Package", "7.0.0", "net8.0"), + MockNuGetPackage.CreateSimplePackage("Transitive.Package", "8.0.0", "net8.0"), ], projectContents: """ diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs index 5690e4ba1c..09ebdccb93 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs @@ -854,30 +854,45 @@ await File.WriteAllTextAsync(projectPath, """ // Two top level packages (Buildalyzer), (Microsoft.CodeAnalysis.CSharp.Scripting) that share a dependency (Microsoft.CodeAnalysis.Csharp) // Updating ONE of the top level packages, which updates the dependencies and their other "parents" - // 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) - // 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) + // First family: Buildalyzer 7.0.1 requires Microsoft.CodeAnalysis.CSharp to be = 4.0.1 and Microsoft.CodeAnalysis.Common to be 4.0.1 (@ 6.0.4, Microsoft.CodeAnalysis.Common isn't a dependency of buildalyzer) + // Second family: Microsoft.CodeAnalysis.CSharp.Scripting 4.0.1 requires Microsoft.CodeAnalysis.CSharp 4.0.1 and Microsoft.CodeAnalysis.Common to be 4.0.1 (Specific version) // Updating Buildalyzer to 7.0.1 will update its transitive dependency (Microsoft.CodeAnalysis.Common) and then its transitive dependency's "family" - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task DependencyConflictsCanBeResolvedNewSharingDependency(bool useExistingSdks) + [Fact] + public async Task DependencyConflictsCanBeResolvedNewSharingDependency() { + // arrange using var tempDirectory = new TemporaryDirectory(); var projectPath = Path.Join(tempDirectory.DirectoryPath, "project.csproj"); await File.WriteAllTextAsync(projectPath, """ - + net8.0 - - + + - + """); + var testPackages = new MockNuGetPackage[] + { + MockNuGetPackage.CreateSimplePackage("Buildalyzer", "6.0.4", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[3.10.0]")])]), + MockNuGetPackage.CreateSimplePackage("Buildalyzer", "7.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.0.1]")])]), + + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "3.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[3.10.0]")])]), + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp.Scripting", "4.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.CSharp", "[4.0.1]")])]), + + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "3.10.0", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[3.10.0]")])]), + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.CSharp", "4.0.1", "net8.0", [(null, [("Microsoft.CodeAnalysis.Common", "[4.0.1]")])]), + + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "3.10.0", "net8.0"), + MockNuGetPackage.CreateSimplePackage("Microsoft.CodeAnalysis.Common", "4.0.1", "net8.0"), + }; + await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(testPackages, tempDirectory.DirectoryPath); + var dependencies = new[] { new Dependency("Buildalyzer", "6.0.4", DependencyType.PackageReference), @@ -890,25 +905,28 @@ await File.WriteAllTextAsync(projectPath, """ new Dependency("Buildalyzer", "7.0.1", DependencyType.PackageReference), }; + // act var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts( tempDirectory.DirectoryPath, projectPath, "net8.0", dependencies, update, - new ExperimentsManager() { InstallDotnetSdks = useExistingSdks }, + new ExperimentsManager(), new TestLogger() ); + + // assert + var expectedDependencies = new[] + { + "Buildalyzer/7.0.1", + "Microsoft.CodeAnalysis.CSharp.Scripting/4.0.1", + "Microsoft.CodeAnalysis.CSharp/4.0.1", + "Microsoft.CodeAnalysis.Common/4.0.1" + }; Assert.NotNull(resolvedDependencies); - Assert.Equal(4, resolvedDependencies.Length); - Assert.Equal("Buildalyzer", resolvedDependencies[0].Name); - Assert.Equal("7.0.1", resolvedDependencies[0].Version); - Assert.Equal("Microsoft.CodeAnalysis.CSharp.Scripting", resolvedDependencies[1].Name); - Assert.Equal("4.0.0", resolvedDependencies[1].Version); - Assert.Equal("Microsoft.CodeAnalysis.CSharp", resolvedDependencies[2].Name); - Assert.Equal("4.0.0", resolvedDependencies[2].Version); - Assert.Equal("Microsoft.CodeAnalysis.Common", resolvedDependencies[3].Name); - Assert.Equal("4.0.0", resolvedDependencies[3].Version); + var actualDependencies = resolvedDependencies.Select(d => $"{d.Name}/{d.Version}").ToArray(); + AssertEx.Equal(expectedDependencies, actualDependencies); } // Updating two families at once to test efficiency diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs index 41e6e8aad5..34fe141ff3 100644 --- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs @@ -395,7 +395,6 @@ public async Task UpdateVersion(List existingPackages, if (await AreAllParentsCompatibleAsync(existingPackages, existingPackage, targetFramework, projectDirectory, logger) == true) { existingPackage.CurrentVersion = dependencyOldVersion; - string NewVersion = dependency.CurrentVersion; existingPackage.NewVersion = dependency.CurrentVersion; await UpdateVersion(existingPackages, existingPackage, targetFramework, projectDirectory, logger); } @@ -593,12 +592,6 @@ public async Task FindCompatibleVersionAsync(List return null; } - // If the current version of the parent is less than the current version of the dependency - else if (CurrentVersion < currentVersionDependency) - { - return currentVersionDependency; - } - // Loop from the current version to the latest version, use next patch as a limit (unless there's a limit) so it doesn't look for versions that don't exist for (NuGetVersion version = CurrentVersion; version <= latestVersion; version = NextPatch(version, versions)) {