Open jeffkl opened 15 hours ago
This test shows the broken behavior:
// P1 -> P2 -> B 2.0.0-preview.*
// P1 -> A -> B 2.0.0-preview.1
[Fact] // TODO: REMOVE
public async Task RestoreCommand_WithPrereleaseTransitiveVersionWithFullyMatchedReleaseLabel_VerifiesEquivalency()
{
// Arrange
using var pathContext = new SimpleTestPathContext();
var versionRange = VersionRange.Parse("2.0.0-preview.*");
await SimpleTestPackageUtility.CreatePackagesAsync(
pathContext.PackageSource,
new SimpleTestPackageContext("a", "1.0.0")
{
Dependencies = [new SimpleTestPackageContext("b", "2.0.0-preview.1")],
},
new SimpleTestPackageContext("b", "2.0.0-preview.2")
);
// Setup project
var spec1 = @"
{
""frameworks"": {
""net472"": {
""dependencies"": {
""a"": {
""version"": ""[1.0.0,)"",
""target"": ""Package"",
},
}
}
}
}";
var spec2 = @"
{
""frameworks"": {
""net472"": {
""dependencies"": {
""b"": {
""version"": """ + versionRange.ToString() + @""",
""target"": ""Package"",
},
}
}
}
}";
// Setup project
var project1 = ProjectTestHelpers.GetPackageSpecWithProjectNameAndSpec("Project1", pathContext.SolutionRoot, spec1);
var project2 = ProjectTestHelpers.GetPackageSpecWithProjectNameAndSpec("Project2", pathContext.SolutionRoot, spec2);
project1 = project1.WithTestProjectReference(project2);
// Act & Assert
(var result, _) = await ValidateRestoreAlgorithmEquivalency(pathContext, project1, project2);
result.Success.Should().BeTrue();
result.LockFile.Targets.Should().HaveCount(1);
result.LockFile.Targets[0].Libraries.Should().HaveCount(3);
result.LockFile.Targets[0].Libraries[0].Name.Should().Be("a");
result.LockFile.Targets[0].Libraries[0].Version.Should().Be(new NuGetVersion("1.0.0"));
result.LockFile.Targets[0].Libraries[1].Name.Should().Be("b");
result.LockFile.Targets[0].Libraries[1].Version.Should().Be(new NuGetVersion("2.0.0-preview.2"));
result.LockFile.Targets[0].Libraries[2].Name.Should().Be("Project2");
result.LockFile.Targets[0].Libraries[2].Version.Should().Be(new NuGetVersion("1.0.0"));
}
And this is a proposed fix I was working on:
ersionRange nvr = currentRef.LibraryRange.VersionRange ?? VersionRange.All;
VersionRange ovr = chosenRef.LibraryRange.VersionRange ?? VersionRange.All;
// First determine if the version range is greater than or equal to the chosen version range.
bool isGreaterThanOrEqual = RemoteDependencyWalker.IsGreaterThanOrEqualTo(ovr, nvr);
// If either version range is floating and the version range is considered equal, we need to compare the resolved version instead
if (isGreaterThanOrEqual && (nvr.IsFloating || ovr.IsFloating) && resolvedItemTask != null)
{
FindLibraryEntryResult resolvedItem = await resolvedItemTask;
NuGetVersion nearVersion = refItemResult.Item.Key.Version;
NuGetVersion farVersion = resolvedItem.Item.Key.Version;
isGreaterThanOrEqual = farVersion >= nearVersion;
}
NuGet Product Used
dotnet.exe, MSBuild.exe
Product Version
6.12
Worked before?
No response
Impact
I'm unable to use this version
Repro Steps & Context
When you have package versions in your graph like
1.0.0-preview.*
and1.0.0-preview.1
, the new dependency resolver does not properly handle it. This is because it currently only compares the version ranges and considers those to be identical. When a floating version is used, the resolver should be comparing the resolved versions instead.Verbose Logs
No response