diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolverEnvironment.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolverEnvironment.cs
new file mode 100644
index 00000000000..7d47ff271ff
--- /dev/null
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolverEnvironment.cs
@@ -0,0 +1,12 @@
+namespace NuGetUpdater.Core.Test;
+
+///
+/// Prepares the environment to use the new dependency solver.
+///
+public class DependencySolverEnvironment : TemporaryEnvironment
+{
+ public DependencySolverEnvironment(bool useDependencySolver = true)
+ : base([("UseNewNugetPackageResolver", useDependencySolver ? "true" : "false")])
+ {
+ }
+}
diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs
index e3bc939c89e..20bc39ebf51 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs
@@ -54,12 +54,12 @@ await TestUpdateForProject("Some.Package", "9.0.1", "13.0.1",
}
[Theory]
- [InlineData("true")]
- [InlineData(null)]
- public async Task UpdateVersionChildElement_InProjectFile_ForPackageReferenceIncludeTheory(string variableValue)
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task UpdateVersionChildElement_InProjectFile_ForPackageReferenceIncludeTheory(bool useDependencySolver)
{
// update Some.Package from 9.0.1 to 13.0.1
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", variableValue)]);
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
await TestUpdateForProject("Some.Package", "9.0.1", "13.0.1",
packages:
[
@@ -95,11 +95,72 @@ await TestUpdateForProject("Some.Package", "9.0.1", "13.0.1",
);
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task PeerDependenciesAreUpdatedEvenWhenNotExplicit(bool useDependencySolver)
+ {
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
+ packages:
+ [
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", [(null, [("Transitive.Package", "[1.0.0]")])]),
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0", [(null, [("Transitive.Package", "[2.0.0]")])]),
+ MockNuGetPackage.CreateSimplePackage("Transitive.Package", "1.0.0", "net8.0"),
+ MockNuGetPackage.CreateSimplePackage("Transitive.Package", "2.0.0", "net8.0"),
+ ],
+ projectFile: ("a/a.csproj", """
+
+
+ net8.0
+ true
+
+
+
+
+
+ """),
+ additionalFiles:
+ [
+ ("Directory.Packages.props", """
+
+
+
+
+
+
+ """)
+ ],
+ expectedProjectContents: """
+
+
+ net8.0
+ true
+
+
+
+
+
+ """,
+ additionalFilesExpected:
+ [
+ ("Directory.Packages.props", """
+
+
+
+
+
+
+ """)
+ ]
+ );
+ }
+
[Fact]
public async Task CallingResolveDependencyConflictsNew()
{
// update Microsoft.CodeAnalysis.Common from 4.9.2 to 4.10.0
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", "true")]);
+ using var _ = new DependencySolverEnvironment();
await TestUpdateForProject("Microsoft.CodeAnalysis.Common", "4.9.2", "4.10.0",
// initial
projectContents: $"""
@@ -535,11 +596,11 @@ await TestUpdateForProject("Some.Package", "9.0.1", "13.0.1",
}
[Theory]
- [InlineData(null)]
- [InlineData("true")]
- public async Task AddPackageReference_InProjectFile_ForTransientDependency(string variableValue)
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task AddPackageReference_InProjectFile_ForTransientDependency(bool useDependencySolver)
{
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", variableValue)]);
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
// add transient package Some.Transient.Dependency from 5.0.1 to 5.0.2
await TestUpdateForProject("Some.Transient.Dependency", "5.0.1", "5.0.2", isTransitive: true,
packages:
@@ -2914,12 +2975,51 @@ await TestUpdateForProject("Some.Package", "12.0.1", "13.0.1",
);
}
+ [Fact]
+ 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
+ using var _ = new DependencySolverEnvironment();
+ await TestUpdateForProject("Transitive.Package", "1.0.0", "2.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"),
+ ],
+ projectContents: """
+
+
+ net8.0
+ false
+
+
+
+
+
+ """,
+ expectedProjectContents: """
+
+
+ net8.0
+ false
+
+
+
+
+
+ """
+ );
+ }
+
[Theory]
- [InlineData("true")]
- [InlineData(null)]
- public async Task NoChange_IfThereAreIncoherentVersions(string variableValue)
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task NoChange_IfThereAreIncoherentVersions(bool useDependencySolver)
{
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", variableValue)]);
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
// trying to update `Transitive.Dependency` to 1.1.0 would normally pull `Some.Package` from 1.0.0 to 1.1.0,
// but the TFM doesn't allow it
@@ -3005,11 +3105,11 @@ await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
}
[Theory]
- [InlineData("true")]
- [InlineData(null)]
- public async Task UnresolvablePropertyDoesNotStopOtherUpdates(string variableValue)
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task UnresolvablePropertyDoesNotStopOtherUpdates(bool useDependencySolver)
{
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", variableValue)]);
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
// the property `$(SomeUnresolvableProperty)` cannot be resolved
await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
@@ -3045,11 +3145,11 @@ await TestUpdateForProject("Some.Package", "7.0.1", "13.0.1",
}
[Theory]
- [InlineData("true")]
- [InlineData(null)]
- public async Task UpdatingPackageAlsoUpdatesAnythingWithADependencyOnTheUpdatedPackage(string variableValue)
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task UpdatingPackageAlsoUpdatesAnythingWithADependencyOnTheUpdatedPackage(bool useDependencySolver)
{
- using var env = new TemporaryEnvironment([("UseNewNugetPackageResolver", variableValue)]);
+ using var _ = new DependencySolverEnvironment(useDependencySolver);
// updating Some.Package from 3.3.30 requires that Some.Package.Extensions also be updated
await TestUpdateForProject("Some.Package", "3.3.30", "3.4.3",
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 337cc4f3fa9..c419bf9faba 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs
@@ -442,9 +442,9 @@ [new Dependency("Package.A", "1.0.0", DependencyType.Unknown)]
}
[Fact]
- public async Task DependencyConflictsCanBeResolved()
+ public async Task DependencyConflictsCanBeResolvedWithBruteForce()
{
- var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolved)}_");
+ var repoRoot = Directory.CreateTempSubdirectory($"test_{nameof(DependencyConflictsCanBeResolvedWithBruteForce)}_");
MockNuGetPackage[] testPackages =
[
// some base packages
@@ -483,7 +483,7 @@ await File.WriteAllTextAsync(projectPath, """
{
new Dependency("Some.Other.Package", "1.2.0", DependencyType.PackageReference),
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsWithBruteForce(repoRoot.FullName, projectPath, "net8.0", dependencies, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(2, resolvedDependencies.Length);
Assert.Equal("Some.Package", resolvedDependencies[0].Name);
@@ -533,7 +533,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("CS-Script.Core", "2.0.0", DependencyType.PackageReference),
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(3, resolvedDependencies.Length);
Assert.Equal("CS-Script.Core", resolvedDependencies[0].Name);
@@ -578,7 +578,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.Bcl.AsyncInterfaces", "1.1.1", DependencyType.Unknown)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Single(resolvedDependencies);
Assert.Equal("Azure.Core", resolvedDependencies[0].Name);
@@ -621,7 +621,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Newtonsoft.Json", "13.0.1", DependencyType.Unknown)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(2, resolvedDependencies.Length);
Assert.Equal("Newtonsoft.Json.Bson", resolvedDependencies[0].Name);
@@ -671,7 +671,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(3, resolvedDependencies.Length);
Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
@@ -723,7 +723,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.CodeAnalysis.Common", "4.10.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(4, resolvedDependencies.Length);
Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
@@ -779,7 +779,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Newtonsoft.Json", "13.0.1", DependencyType.Unknown)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(5, resolvedDependencies.Length);
Assert.Equal("Microsoft.CodeAnalysis.Compilers", resolvedDependencies[0].Name);
@@ -838,7 +838,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Buildalyzer", "7.0.1", DependencyType.PackageReference),
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(4, resolvedDependencies.Length);
Assert.Equal("Buildalyzer", resolvedDependencies[0].Name);
@@ -895,7 +895,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Azure.Core", "1.22.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(4, resolvedDependencies.Length);
Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
@@ -952,7 +952,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Azure.Core", "1.22.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(5, resolvedDependencies.Length);
Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
@@ -1007,7 +1007,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("AutoMapper.Collection", "10.0.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(3, resolvedDependencies.Length);
Assert.Equal("AutoMapper.Extensions.Microsoft.DependencyInjection", resolvedDependencies[0].Name);
@@ -1054,7 +1054,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.Extensions.Caching.Memory", "8.0.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(2, resolvedDependencies.Length);
Assert.Equal("Microsoft.EntityFrameworkCore", resolvedDependencies[0].Name);
@@ -1104,7 +1104,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(4, resolvedDependencies.Length);
Assert.Equal("Microsoft.EntityFrameworkCore.Design", resolvedDependencies[0].Name);
@@ -1156,7 +1156,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("Microsoft.EntityFrameworkCore.Analyzers", "8.0.0", DependencyType.PackageReference)
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(3, resolvedDependencies.Length);
Assert.Equal("Microsoft.EntityFrameworkCore.Design", resolvedDependencies[0].Name);
@@ -1208,7 +1208,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("System.Collections.Immutable", "8.0.0", DependencyType.PackageReference),
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(4, resolvedDependencies.Length);
Assert.Equal("System.Collections.Immutable", resolvedDependencies[0].Name);
@@ -1260,7 +1260,7 @@ await File.WriteAllTextAsync(projectPath, """
new Dependency("System.Collections.Immutable", "8.0.0", DependencyType.PackageReference),
};
- var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsNew(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRoot.FullName, projectPath, "net8.0", dependencies, update, new TestLogger());
Assert.NotNull(resolvedDependencies);
Assert.Equal(3, resolvedDependencies.Length);
Assert.Equal("Microsoft.CodeAnalysis.CSharp.Workspaces", resolvedDependencies[0].Name);
diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs
index 7513e075ad3..b3da76eaaae 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs
@@ -30,19 +30,26 @@ public static async Task UpdateDependencyAsync(
return;
}
- if (isTransitive)
+ var peerDependencies = await GetUpdatedPeerDependenciesAsync(repoRootPath, projectPath, tfms, dependencyName, newDependencyVersion, logger);
+ if (MSBuildHelper.UseNewDependencySolver())
{
- await UpdateTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, buildFiles, logger);
+ await UpdateDependencyWithConflictResolution(repoRootPath, buildFiles, tfms, projectPath, dependencyName, previousDependencyVersion, newDependencyVersion, isTransitive, peerDependencies, logger);
}
else
{
- var peerDependencies = await GetUpdatedPeerDependenciesAsync(repoRootPath, projectPath, tfms, dependencyName, newDependencyVersion, logger);
- if (peerDependencies is null)
+ if (isTransitive)
{
- return;
+ await UpdateTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, buildFiles, logger);
}
+ else
+ {
+ if (peerDependencies is null)
+ {
+ return;
+ }
- await UpdateTopLevelDepdendency(repoRootPath, buildFiles, tfms, dependencyName, previousDependencyVersion, newDependencyVersion, peerDependencies, logger);
+ await UpdateTopLevelDepdendency(repoRootPath, buildFiles, tfms, dependencyName, previousDependencyVersion, newDependencyVersion, peerDependencies, logger);
+ }
}
if (!await AreDependenciesCoherentAsync(repoRootPath, projectPath, dependencyName, logger, buildFiles, tfms))
@@ -53,6 +60,61 @@ public static async Task UpdateDependencyAsync(
await SaveBuildFilesAsync(buildFiles, logger);
}
+ public static async Task UpdateDependencyWithConflictResolution(
+ string repoRootPath,
+ ImmutableArray buildFiles,
+ string[] targetFrameworks,
+ string projectPath,
+ string dependencyName,
+ string previousDependencyVersion,
+ string newDependencyVersion,
+ bool isTransitive,
+ IDictionary peerDependencies,
+ ILogger logger)
+ {
+ var topLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles).ToArray();
+ var isDependencyTopLevel = topLevelDependencies.Any(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase));
+ var dependenciesToUpdate = new[] { new Dependency(dependencyName, newDependencyVersion, DependencyType.PackageReference) };
+
+ // update the initial dependency...
+ TryUpdateDependencyVersion(buildFiles, dependencyName, previousDependencyVersion, newDependencyVersion, logger);
+
+ // ...and the peer dependencies...
+ foreach (var (packageName, packageVersion) in peerDependencies.Where(kvp => string.Compare(kvp.Key, dependencyName, StringComparison.OrdinalIgnoreCase) != 0))
+ {
+ TryUpdateDependencyVersion(buildFiles, packageName, previousDependencyVersion: null, newDependencyVersion: packageVersion, logger);
+ }
+
+ // ...and everything else
+ foreach (var projectFile in buildFiles)
+ {
+ foreach (var tfm in targetFrameworks)
+ {
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRootPath, projectFile.Path, tfm, topLevelDependencies, dependenciesToUpdate, logger);
+ if (resolvedDependencies is null)
+ {
+ logger.Log($" Unable to resolve dependency conflicts for {projectFile.Path}.");
+ continue;
+ }
+
+ var isDependencyInResolutionSet = resolvedDependencies.Any(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase));
+ if (isTransitive && !isDependencyTopLevel && isDependencyInResolutionSet)
+ {
+ // a transitive dependency had to be pinned; add it here
+ await UpdateTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, buildFiles, logger);
+ }
+
+ // update all resolved dependencies that aren't the initial dependency
+ foreach (var resolvedDependency in resolvedDependencies
+ .Where(d => !d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase))
+ .Where(d => d.Version is not null))
+ {
+ TryUpdateDependencyVersion(buildFiles, resolvedDependency.Name, previousDependencyVersion: null, newDependencyVersion: resolvedDependency.Version!, logger);
+ }
+ }
+ }
+ }
+
///
/// Verifies that the package does not already satisfy the requested dependency version.
///
@@ -307,7 +369,7 @@ private static async Task UpdateTopLevelDepdendency(
IDictionary peerDependencies,
ILogger logger)
{
-
+ // update dependencies...
var result = TryUpdateDependencyVersion(buildFiles, dependencyName, previousDependencyVersion, newDependencyVersion, logger);
if (result == UpdateResult.NotFound)
{
@@ -320,26 +382,13 @@ private static async Task UpdateTopLevelDepdendency(
TryUpdateDependencyVersion(buildFiles, packageName, previousDependencyVersion: null, newDependencyVersion: packageVersion, logger);
}
- // now make all dependency requirements coherent
+ // ...and make them all coherent
Dependency[] updatedTopLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles).ToArray();
foreach (ProjectBuildFile projectFile in buildFiles)
{
foreach (string tfm in targetFrameworks)
{
- if (MSBuildHelper.UseNewDependencySolver())
- {
- // Find the index of the dependency we are updating and revert it to the previous version
- int dependencyIndex = Array.FindIndex(updatedTopLevelDependencies, d => string.Equals(d.Name, dependencyName, StringComparison.OrdinalIgnoreCase));
- if (dependencyIndex != -1)
- {
- var originalDependency = updatedTopLevelDependencies[dependencyIndex];
- updatedTopLevelDependencies[dependencyIndex] = originalDependency with { Version = previousDependencyVersion };
- }
-
- }
- Dependency[] update = [new Dependency(dependencyName, newDependencyVersion, DependencyType.PackageReference)];
- Dependency[]? resolvedDependencies = await MSBuildHelper.ResolveDependencyConflicts(repoRootPath, projectFile.Path, tfm, updatedTopLevelDependencies, update, logger);
-
+ var resolvedDependencies = await MSBuildHelper.ResolveDependencyConflictsWithBruteForce(repoRootPath, projectFile.Path, tfm, updatedTopLevelDependencies, logger);
if (resolvedDependencies is null)
{
logger.Log($" Unable to resolve dependency conflicts for {projectFile.Path}.");
@@ -360,7 +409,7 @@ private static async Task UpdateTopLevelDepdendency(
continue;
}
- // update all dependencies
+ // update all versions
foreach (Dependency resolvedDependency in resolvedDependencies
.Where(d => !d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase))
.Where(d => d.Version is not null))
diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs
index d1998d925c7..2d65c39aba6 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs
@@ -341,18 +341,6 @@ internal static bool UseNewDependencySolver()
}
internal static async Task ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Dependency[] update, ILogger logger)
- {
- if (UseNewDependencySolver())
- {
- return await ResolveDependencyConflictsNew(repoRoot, projectPath, targetFramework, packages, update, logger);
- }
- else
- {
- return await ResolveDependencyConflictsOld(repoRoot, projectPath, targetFramework, packages, logger);
- }
- }
-
- internal static async Task ResolveDependencyConflictsNew(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Dependency[] update, ILogger logger)
{
var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
PackageManager packageManager = new PackageManager(repoRoot, projectPath);
@@ -510,7 +498,7 @@ internal static bool UseNewDependencySolver()
}
}
- internal static async Task ResolveDependencyConflictsOld(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, ILogger logger)
+ internal static async Task ResolveDependencyConflictsWithBruteForce(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, ILogger logger)
{
var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
try