Skip to content

Commit d507e81

Browse files
committed
SemVer 2.0.0 version ranges imply that the package itself is SemVer 2.0.0
Fix NuGet/NuGetGallery#3657 for master
1 parent 97d568b commit d507e81

7 files changed

Lines changed: 145 additions & 10 deletions

File tree

src/NuGet.Server/Infrastructure/JsonNetPackagesSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace NuGet.Server.Infrastructure
1313
public class JsonNetPackagesSerializer
1414
: IPackagesSerializer
1515
{
16-
private static readonly SemanticVersion CurrentSchemaVersion = new SemanticVersion("2.0.0");
16+
private static readonly SemanticVersion CurrentSchemaVersion = new SemanticVersion("3.0.0");
1717

1818
private readonly JsonSerializer _serializer = new JsonSerializer
1919
{

src/NuGet.Server/Infrastructure/ServerPackage.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public ServerPackage(IPackage package, PackageDerivedData packageDerivedData)
4646
Listed = package.Listed;
4747
Published = package.Published;
4848

49+
IsSemVer2 = IsPackageSemVer2(package);
50+
4951
_dependencySets = package.DependencySets.ToList();
5052
Dependencies = DependencySetsAsString(package.DependencySets);
5153

@@ -147,9 +149,9 @@ public IEnumerable<FrameworkName> GetSupportedFrameworks()
147149
return _supportedFrameworks;
148150
}
149151

150-
public bool IsAbsoluteLatestVersion => SemVer2IsAbsoluteLatest;
152+
public bool IsAbsoluteLatestVersion => IsSemVer2 ? SemVer2IsAbsoluteLatest : SemVer1IsAbsoluteLatest;
151153

152-
public bool IsLatestVersion => SemVer2IsLatest;
154+
public bool IsLatestVersion => IsSemVer2 ? SemVer2IsLatest : SemVer1IsLatest;
153155

154156
public bool SemVer1IsAbsoluteLatest { get; set; }
155157

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

164166
public DateTimeOffset? Published { get; set; }
165167

168+
public bool IsSemVer2 { get; set; }
166169

167170
public long PackageSize { get; set; }
168171

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

265+
private static bool IsPackageSemVer2(IPackage package)
266+
{
267+
if (package.Version.IsSemVer2())
268+
{
269+
return true;
270+
}
271+
272+
if (package.DependencySets != null)
273+
{
274+
foreach (var dependencySet in package.DependencySets)
275+
{
276+
foreach (var dependency in dependencySet.Dependencies)
277+
{
278+
var range = dependency.VersionSpec;
279+
if (range == null)
280+
{
281+
continue;
282+
}
283+
284+
if (range.MinVersion != null && range.MinVersion.IsSemVer2())
285+
{
286+
return true;
287+
}
288+
289+
if (range.MaxVersion != null && range.MaxVersion.IsSemVer2())
290+
{
291+
return true;
292+
}
293+
}
294+
}
295+
}
296+
297+
298+
return false;
299+
}
262300

263301
#region Unsupported operations
264302

src/NuGet.Server/Infrastructure/ServerPackageRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public IQueryable<ServerPackage> GetPackages(ClientCompatibility compatibility)
122122

123123
if (!compatibility.AllowSemVer2)
124124
{
125-
cache = cache.Where(p => !p.Version.IsSemVer2());
125+
cache = cache.Where(p => !p.IsSemVer2);
126126
}
127127

128128
return cache;

src/NuGet.Server/Infrastructure/ServerPackageStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ private static void UpdateLatestVersions(IEnumerable<ServerPackage> packages)
185185
package.SemVer2IsLatest = false;
186186

187187
// Update the SemVer1 views.
188-
if (!package.Version.IsSemVer2())
188+
if (!package.IsSemVer2)
189189
{
190190
UpdateLatestDictionary(semVer1AbsoluteLatest, package);
191191

test/NuGet.Server.Tests/NuGet.Server.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
<Compile Include="SemanticVersionJsonConverterTests.cs" />
114114
<Compile Include="ServerPackageRepositoryTest.cs" />
115115
<Compile Include="ServerPackageStoreTest.cs" />
116+
<Compile Include="ServerPackageTest.cs" />
116117
</ItemGroup>
117118
<ItemGroup>
118119
<ProjectReference Include="..\..\src\NuGet.Server\NuGet.Server.csproj">

test/NuGet.Server.Tests/ServerPackageStoreTest.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ public class ServerPackageStoreTest
3030
[InlineData("[{\"foo\": \"bar\"}]")]
3131
[InlineData("{\"SchemaVersion\":null,\"Packages\":[]}")]
3232
[InlineData("{\"SchemaVersion\":\"1.0.0\",\"Packages\":null}")]
33-
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[]}")]
33+
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":null}")]
34+
[InlineData("{\"SchemaVersion\":\"4.0.0\",\"Packages\":[]}")]
3435
[InlineData("{\"Packages\":[]}")]
35-
[InlineData("{\"SchemaVersion\":\"2.0.0\"}")]
36+
[InlineData("{\"SchemaVersion\":\"3.0.0\"}")]
3637
public void Constructor_IgnoresAndDeletesInvalidCacheFile(string content)
3738
{
3839
// Arrange
@@ -53,8 +54,8 @@ public void Constructor_IgnoresAndDeletesInvalidCacheFile(string content)
5354
}
5455

5556
[Theory]
56-
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":[]}", 0)]
57-
[InlineData("{\"SchemaVersion\":\"2.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + PackageVersionString + "\"}]}", 1)]
57+
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[]}", 0)]
58+
[InlineData("{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + PackageVersionString + "\"}]}", 1)]
5859
public void Constructor_LeavesValidCacheFile(string content, int count)
5960
{
6061
// Arrange
@@ -78,7 +79,7 @@ public void Constructor_LeavesValidCacheFile(string content, int count)
7879
public void Constructor_DeserializesSemVer2Version()
7980
{
8081
// Arrange
81-
var cacheFile = "{\"SchemaVersion\":\"2.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\"}]}";
82+
var cacheFile = "{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\"}]}";
8283
var fileSystem = new Mock<IFileSystem>();
8384
fileSystem
8485
.Setup(x => x.FileExists(CacheFileName))
@@ -98,6 +99,30 @@ public void Constructor_DeserializesSemVer2Version()
9899
Assert.Equal(SemVer2Version.ToNormalizedString(), package.Version.ToNormalizedString());
99100
}
100101

102+
[Theory]
103+
[InlineData("true", true)]
104+
[InlineData("false", false)]
105+
public void Constructor_DeserializesIsSemVer2(string serialized, bool expected)
106+
{
107+
// Arrange
108+
var cacheFile = "{\"SchemaVersion\":\"3.0.0\",\"Packages\":[{\"Id\":\"" + PackageId + "\",\"Version\":\"" + SemVer2VersionString + "\",\"IsSemVer2\":" + serialized + "}]}";
109+
var fileSystem = new Mock<IFileSystem>();
110+
fileSystem
111+
.Setup(x => x.FileExists(CacheFileName))
112+
.Returns(true);
113+
fileSystem
114+
.Setup(x => x.OpenFile(CacheFileName))
115+
.Returns(() => new MemoryStream(Encoding.UTF8.GetBytes(cacheFile)));
116+
117+
// Act
118+
var actual = new ServerPackageStore(fileSystem.Object, CacheFileName);
119+
120+
// Assert
121+
Assert.Equal(1, actual.GetAll().Count());
122+
var package = actual.GetAll().First();
123+
Assert.Equal(expected, package.IsSemVer2);
124+
}
125+
101126
[Fact]
102127
public void Persist_RetainsSemVer2Version()
103128
{
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Linq;
5+
using System.Runtime.Versioning;
6+
using Moq;
7+
using NuGet.Server.Infrastructure;
8+
using Xunit;
9+
10+
namespace NuGet.Server.Tests
11+
{
12+
public class ServerPackageTest
13+
{
14+
[Theory]
15+
[InlineData("1.0.0", false)]
16+
[InlineData("1.0.0-alpha", false)]
17+
[InlineData("1.0.0-alpha.1", true)]
18+
[InlineData("1.0.0+githash", true)]
19+
[InlineData("1.0.0-alpha+githash", true)]
20+
[InlineData("1.0.0-alpha.1+githash", true)]
21+
public void IsSemVer2_CanBeDeterminedByPackageVersion(string version, bool isSemVer2)
22+
{
23+
// Arrange
24+
var package = new Mock<IPackage>();
25+
package.Setup(x => x.Version).Returns(new SemanticVersion(version));
26+
var packageDerivedData = new PackageDerivedData();
27+
28+
// Act
29+
var serverPackage = new ServerPackage(package.Object, packageDerivedData);
30+
31+
// Assert
32+
Assert.Equal(isSemVer2, serverPackage.IsSemVer2);
33+
}
34+
35+
[Theory]
36+
[InlineData("1.0.0", false)]
37+
[InlineData("1.0.0-alpha", false)]
38+
[InlineData("1.0.0-alpha.1", true)]
39+
[InlineData("[1.0.0-alpha.1, 2.0.0)", true)]
40+
[InlineData("[1.0.0+githash, 2.0.0)", true)]
41+
[InlineData("[1.0.0-alpha, 2.0.0-alpha.1)", true)]
42+
[InlineData("[1.0.0, 2.0.0+githash)", true)]
43+
[InlineData("[1.0.0-alpha, 2.0.0)", false)]
44+
public void IsSemVer2_CanBeDeterminedByDependencyVersionRange(string versionRange, bool isSemVer2)
45+
{
46+
// Arrange
47+
var package = new Mock<IPackage>();
48+
package
49+
.Setup(x => x.Version)
50+
.Returns(new SemanticVersion("1.0.0"));
51+
package
52+
.Setup(x => x.DependencySets)
53+
.Returns(new[]
54+
{
55+
new PackageDependencySet(
56+
new FrameworkName(".NETFramework,Version=v4.5"),
57+
new[]
58+
{
59+
new PackageDependency("OtherPackage", VersionUtility.ParseVersionSpec(versionRange))
60+
})
61+
}.AsEnumerable());
62+
var packageDerivedData = new PackageDerivedData();
63+
64+
// Act
65+
var serverPackage = new ServerPackage(package.Object, packageDerivedData);
66+
67+
// Assert
68+
Assert.Equal(isSemVer2, serverPackage.IsSemVer2);
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)