Skip to content

Commit

Permalink
don't use transitive dependency version as top level version
Browse files Browse the repository at this point in the history
  • Loading branch information
brettfo committed Dec 18, 2024
1 parent ba0bbf8 commit 22e29b1
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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: """
<Project Sdk="Microsoft.NET.Sdk">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, """
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Buildalyzer" Version="6.0.4" />
<PackageReference Include="Microsoft.CodeAnalysis.Csharp.Scripting" Version="3.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" />
</ItemGroup>
</ItemGroup>
</Project>
""");

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),
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,6 @@ public async Task<string> UpdateVersion(List<PackageToUpdate> 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);
}
Expand Down Expand Up @@ -593,12 +592,6 @@ public async Task<NuGetVersion> FindCompatibleVersionAsync(List<PackageToUpdate>
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))
{
Expand Down

0 comments on commit 22e29b1

Please sign in to comment.