Skip to content

Commit

Permalink
SemVer 2.0.0 version ranges imply that the package itself is SemVer 2…
Browse files Browse the repository at this point in the history
….0.0

Fix NuGet/NuGetGallery#3657 for master
  • Loading branch information
joelverhagen committed Mar 17, 2017
1 parent 97d568b commit d507e81
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NuGet.Server.Infrastructure
public class JsonNetPackagesSerializer
: IPackagesSerializer
{
private static readonly SemanticVersion CurrentSchemaVersion = new SemanticVersion("2.0.0");
private static readonly SemanticVersion CurrentSchemaVersion = new SemanticVersion("3.0.0");

private readonly JsonSerializer _serializer = new JsonSerializer
{
Expand Down
42 changes: 40 additions & 2 deletions src/NuGet.Server/Infrastructure/ServerPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public ServerPackage(IPackage package, PackageDerivedData packageDerivedData)
Listed = package.Listed;
Published = package.Published;

IsSemVer2 = IsPackageSemVer2(package);

_dependencySets = package.DependencySets.ToList();
Dependencies = DependencySetsAsString(package.DependencySets);

Expand Down Expand Up @@ -147,9 +149,9 @@ public IEnumerable<FrameworkName> GetSupportedFrameworks()
return _supportedFrameworks;
}

public bool IsAbsoluteLatestVersion => SemVer2IsAbsoluteLatest;
public bool IsAbsoluteLatestVersion => IsSemVer2 ? SemVer2IsAbsoluteLatest : SemVer1IsAbsoluteLatest;

public bool IsLatestVersion => SemVer2IsLatest;
public bool IsLatestVersion => IsSemVer2 ? SemVer2IsLatest : SemVer1IsLatest;

public bool SemVer1IsAbsoluteLatest { get; set; }

Expand All @@ -163,6 +165,7 @@ public IEnumerable<FrameworkName> GetSupportedFrameworks()

public DateTimeOffset? Published { get; set; }

public bool IsSemVer2 { get; set; }

public long PackageSize { get; set; }

Expand Down Expand Up @@ -259,6 +262,41 @@ private static Tuple<string, IVersionSpec, FrameworkName> ParseDependency(string
return Tuple.Create(id, versionSpec, targetFramework);
}

private static bool IsPackageSemVer2(IPackage package)
{
if (package.Version.IsSemVer2())
{
return true;
}

if (package.DependencySets != null)
{
foreach (var dependencySet in package.DependencySets)
{
foreach (var dependency in dependencySet.Dependencies)
{
var range = dependency.VersionSpec;
if (range == null)
{
continue;
}

if (range.MinVersion != null && range.MinVersion.IsSemVer2())
{
return true;
}

if (range.MaxVersion != null && range.MaxVersion.IsSemVer2())
{
return true;
}
}
}
}


return false;
}

#region Unsupported operations

Expand Down
2 changes: 1 addition & 1 deletion src/NuGet.Server/Infrastructure/ServerPackageRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public IQueryable<ServerPackage> GetPackages(ClientCompatibility compatibility)

if (!compatibility.AllowSemVer2)
{
cache = cache.Where(p => !p.Version.IsSemVer2());
cache = cache.Where(p => !p.IsSemVer2);
}

return cache;
Expand Down
2 changes: 1 addition & 1 deletion src/NuGet.Server/Infrastructure/ServerPackageStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private static void UpdateLatestVersions(IEnumerable<ServerPackage> packages)
package.SemVer2IsLatest = false;
// Update the SemVer1 views.
if (!package.Version.IsSemVer2())
if (!package.IsSemVer2)
{
UpdateLatestDictionary(semVer1AbsoluteLatest, package);
Expand Down
1 change: 1 addition & 0 deletions test/NuGet.Server.Tests/NuGet.Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
<Compile Include="SemanticVersionJsonConverterTests.cs" />
<Compile Include="ServerPackageRepositoryTest.cs" />
<Compile Include="ServerPackageStoreTest.cs" />
<Compile Include="ServerPackageTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NuGet.Server\NuGet.Server.csproj">
Expand Down
35 changes: 30 additions & 5 deletions test/NuGet.Server.Tests/ServerPackageStoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ public class ServerPackageStoreTest
[InlineData("[{\"foo\": \"bar\"}]")]
[InlineData("{\"SchemaVersion\":null,\"Packages\":[]}")]
[InlineData("{\"SchemaVersion\":\"1.0.0\",\"Packages\":null}")]
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[]}")]
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":null}")]
[InlineData("{\"SchemaVersion\":\"4.0.0\",\"Packages\":[]}")]
[InlineData("{\"Packages\":[]}")]
[InlineData("{\"SchemaVersion\":\"2.0.0\"}")]
[InlineData("{\"SchemaVersion\":\"3.0.0\"}")]
public void Constructor_IgnoresAndDeletesInvalidCacheFile(string content)
{
// Arrange
Expand All @@ -53,8 +54,8 @@ public void Constructor_IgnoresAndDeletesInvalidCacheFile(string content)
}

[Theory]
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":[]}", 0)]
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + PackageVersionString + "\"}]}", 1)]
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[]}", 0)]
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + PackageVersionString + "\"}]}", 1)]
public void Constructor_LeavesValidCacheFile(string content, int count)
{
// Arrange
Expand All @@ -78,7 +79,7 @@ public void Constructor_LeavesValidCacheFile(string content, int count)
public void Constructor_DeserializesSemVer2Version()
{
// Arrange
var cacheFile = "{\"SchemaVersion\":\"2.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\"}]}";
var cacheFile = "{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\"}]}";
var fileSystem = new Mock<IFileSystem>();
fileSystem
.Setup(x => x.FileExists(CacheFileName))
Expand All @@ -98,6 +99,30 @@ public void Constructor_DeserializesSemVer2Version()
Assert.Equal(SemVer2Version.ToNormalizedString(), package.Version.ToNormalizedString());
}

[Theory]
[InlineData("true", true)]
[InlineData("false", false)]
public void Constructor_DeserializesIsSemVer2(string serialized, bool expected)
{
// Arrange
var cacheFile = "{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\",\"IsSemVer2\":" + serialized + "}]}";
var fileSystem = new Mock<IFileSystem>();
fileSystem
.Setup(x => x.FileExists(CacheFileName))
.Returns(true);
fileSystem
.Setup(x => x.OpenFile(CacheFileName))
.Returns(() => new MemoryStream(Encoding.UTF8.GetBytes(cacheFile)));

// Act
var actual = new ServerPackageStore(fileSystem.Object, CacheFileName);

// Assert
Assert.Equal(1, actual.GetAll().Count());
var package = actual.GetAll().First();
Assert.Equal(expected, package.IsSemVer2);
}

[Fact]
public void Persist_RetainsSemVer2Version()
{
Expand Down
71 changes: 71 additions & 0 deletions test/NuGet.Server.Tests/ServerPackageTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Linq;
using System.Runtime.Versioning;
using Moq;
using NuGet.Server.Infrastructure;
using Xunit;

namespace NuGet.Server.Tests
{
public class ServerPackageTest
{
[Theory]
[InlineData("1.0.0", false)]
[InlineData("1.0.0-alpha", false)]
[InlineData("1.0.0-alpha.1", true)]
[InlineData("1.0.0+githash", true)]
[InlineData("1.0.0-alpha+githash", true)]
[InlineData("1.0.0-alpha.1+githash", true)]
public void IsSemVer2_CanBeDeterminedByPackageVersion(string version, bool isSemVer2)
{
// Arrange
var package = new Mock<IPackage>();
package.Setup(x => x.Version).Returns(new SemanticVersion(version));
var packageDerivedData = new PackageDerivedData();

// Act
var serverPackage = new ServerPackage(package.Object, packageDerivedData);

// Assert
Assert.Equal(isSemVer2, serverPackage.IsSemVer2);
}

[Theory]
[InlineData("1.0.0", false)]
[InlineData("1.0.0-alpha", false)]
[InlineData("1.0.0-alpha.1", true)]
[InlineData("[1.0.0-alpha.1, 2.0.0)", true)]
[InlineData("[1.0.0+githash, 2.0.0)", true)]
[InlineData("[1.0.0-alpha, 2.0.0-alpha.1)", true)]
[InlineData("[1.0.0, 2.0.0+githash)", true)]
[InlineData("[1.0.0-alpha, 2.0.0)", false)]
public void IsSemVer2_CanBeDeterminedByDependencyVersionRange(string versionRange, bool isSemVer2)
{
// Arrange
var package = new Mock<IPackage>();
package
.Setup(x => x.Version)
.Returns(new SemanticVersion("1.0.0"));
package
.Setup(x => x.DependencySets)
.Returns(new[]
{
new PackageDependencySet(
new FrameworkName(".NETFramework,Version=v4.5"),
new[]
{
new PackageDependency("OtherPackage", VersionUtility.ParseVersionSpec(versionRange))
})
}.AsEnumerable());
var packageDerivedData = new PackageDerivedData();

// Act
var serverPackage = new ServerPackage(package.Object, packageDerivedData);

// Assert
Assert.Equal(isSemVer2, serverPackage.IsSemVer2);
}
}
}

0 comments on commit d507e81

Please sign in to comment.