Skip to content

Commit dff7071

Browse files
author
Daniel Jacinto
authored
Revert "Revert "[TFM Display] Create model for badges and table from compatible frameworks. (#8881)"" (#8927)
This reverts commit 51e149b.
1 parent cea4fa1 commit dff7071

10 files changed

Lines changed: 514 additions & 12 deletions

src/NuGetGallery.Core/Frameworks/FrameworkCompatibilityService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ public ISet<NuGetFramework> GetCompatibleFrameworks(IEnumerable<NuGetFramework>
3333
{
3434
allCompatibleFrameworks.UnionWith(compatibleFrameworks);
3535
}
36+
else
37+
{
38+
allCompatibleFrameworks.Add(packageFramework);
39+
}
3640
}
3741

3842
return allCompatibleFrameworks;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
namespace NuGetGallery.Frameworks
5+
{
6+
public static class FrameworkProductNames
7+
{
8+
public const string Net = ".NET";
9+
public const string NetCore = ".NET Core";
10+
public const string NetStandard = ".NET Standard";
11+
public const string NetFramework = ".NET Framework";
12+
public const string NetMicroFramework = ".NET Micro Framework";
13+
public const string UWP = "Universal Windows Platform";
14+
public const string WindowsPhone = "Windows Phone";
15+
public const string WindowsStore = "Windows Store";
16+
}
17+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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 NuGet.Frameworks;
5+
using System.Collections.Generic;
6+
7+
namespace NuGetGallery.Frameworks
8+
{
9+
public class PackageFrameworkCompatibility
10+
{
11+
/// <summary>
12+
/// Contains a <see cref="NuGetFramework"/> for each of the .NET product (.NET, .NET Core, .NET Standard, and .NET Framework).
13+
/// </summary>
14+
public PackageFrameworkCompatibilityBadges Badges { get; set; }
15+
16+
/// <summary>
17+
/// Contains a dictionary filled with all the package asset frameworks and all the computed compatible frameworks retrieved from <see cref="FrameworkCompatibilityService"/>.<br></br>
18+
/// </summary>
19+
/// <remarks>
20+
/// Key: Is the <see cref="FrameworkProductNames"/> if resolved on (<seealso cref="PackageFrameworkCompatibilityFactory.ResolveFrameworkProductName(NuGetFramework)"/>) or the <see cref="NuGetFramework.Framework"/>.<br></br>
21+
/// Value: Is an ordered collection containing all the compatible frameworks.
22+
/// </remarks>
23+
public IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> Table { get; set; }
24+
}
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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 NuGet.Frameworks;
5+
6+
namespace NuGetGallery.Frameworks
7+
{
8+
/// <summary>
9+
/// Contains a <see cref="NuGetFramework"/> for each of the .NET product (.NET, .NET Core, .NET Standard, and .NET Framework).
10+
/// </summary>
11+
/// <remarks>
12+
/// All these properties are retrieved from the <see cref="PackageFrameworkCompatibility.Table"/>, one for each .NET product.<br></br>
13+
/// Only package asset frameworks are considered. i.e. <see cref="PackageFrameworkCompatibilityTableData.IsComputed"/> <c>= false</c>.<br></br>
14+
/// If there are no package asset frameworks for a particular .NET product, then the value will be <c>null</c>.
15+
/// </remarks>
16+
public class PackageFrameworkCompatibilityBadges
17+
{
18+
public NuGetFramework Net { get; set; }
19+
public NuGetFramework NetCore { get; set; }
20+
public NuGetFramework NetStandard { get; set; }
21+
public NuGetFramework NetFramework { get; set; }
22+
}
23+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using NuGet.Frameworks;
8+
using NuGet.Services.Entities;
9+
10+
namespace NuGetGallery.Frameworks
11+
{
12+
public class PackageFrameworkCompatibilityFactory
13+
{
14+
private readonly ISet<Version> WindowsStoreNetCoreVersions = new HashSet<Version> { FrameworkConstants.EmptyVersion, Version.Parse("4.5.0.0"), Version.Parse("4.5.1.0") };
15+
private readonly ISet<Version> WindowsStoreWindowsVersions = new HashSet<Version> { FrameworkConstants.EmptyVersion, Version.Parse("8.0.0.0"), Version.Parse("8.1.0.0") };
16+
private readonly NuGetFrameworkSorter Sorter = new NuGetFrameworkSorter();
17+
private readonly int NetStartingMajorVersion = 5;
18+
19+
private readonly IFrameworkCompatibilityService _compatibilityService;
20+
21+
public PackageFrameworkCompatibilityFactory(IFrameworkCompatibilityService compatibilityService)
22+
{
23+
_compatibilityService = compatibilityService ?? throw new ArgumentNullException();
24+
}
25+
26+
public PackageFrameworkCompatibility Create(ICollection<PackageFramework> packageFrameworks)
27+
{
28+
if (packageFrameworks == null)
29+
{
30+
throw new ArgumentNullException(nameof(packageFrameworks));
31+
}
32+
33+
var filteredPackageFrameworks = packageFrameworks
34+
.Select(pf => pf.FrameworkName)
35+
.Where(f => !f.IsUnsupported && !f.IsPCL)
36+
.ToHashSet();
37+
38+
var table = CreateFrameworkCompatibilityTable(filteredPackageFrameworks);
39+
var badges = CreateFrameworkCompatibilityBadges(table);
40+
41+
return new PackageFrameworkCompatibility
42+
{
43+
Badges = badges,
44+
Table = table
45+
};
46+
}
47+
48+
private IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> CreateFrameworkCompatibilityTable(ICollection<NuGetFramework> filteredPackageFrameworks)
49+
{
50+
var compatibleFrameworks = _compatibilityService.GetCompatibleFrameworks(filteredPackageFrameworks);
51+
52+
var table = new Dictionary<string, ICollection<PackageFrameworkCompatibilityTableData>>();
53+
54+
foreach (var compatibleFramework in compatibleFrameworks)
55+
{
56+
var productName = ResolveFrameworkProductName(compatibleFramework);
57+
var data = new PackageFrameworkCompatibilityTableData
58+
{
59+
Framework = compatibleFramework,
60+
IsComputed = !filteredPackageFrameworks.Contains(compatibleFramework)
61+
};
62+
63+
if (table.TryGetValue(productName, out var allCompatibleFrameworks))
64+
{
65+
allCompatibleFrameworks.Add(data);
66+
}
67+
else
68+
{
69+
var newCompatibleFrameworks = new SortedSet<PackageFrameworkCompatibilityTableData>
70+
(Comparer<PackageFrameworkCompatibilityTableData>.Create((a, b) => Sorter.Compare(a.Framework, b.Framework)));
71+
72+
newCompatibleFrameworks.Add(data);
73+
table.Add(productName, newCompatibleFrameworks);
74+
}
75+
}
76+
77+
return table;
78+
}
79+
80+
private string ResolveFrameworkProductName(NuGetFramework framework)
81+
{
82+
// See: https://docs.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-frameworks
83+
switch (framework.Framework)
84+
{
85+
case FrameworkConstants.FrameworkIdentifiers.NetCoreApp:
86+
return framework.Version.Major >= NetStartingMajorVersion ? FrameworkProductNames.Net : FrameworkProductNames.NetCore;
87+
case FrameworkConstants.FrameworkIdentifiers.NetStandard:
88+
case FrameworkConstants.FrameworkIdentifiers.NetStandardApp:
89+
return FrameworkProductNames.NetStandard;
90+
case FrameworkConstants.FrameworkIdentifiers.Net:
91+
return FrameworkProductNames.NetFramework;
92+
case FrameworkConstants.FrameworkIdentifiers.NetMicro:
93+
return FrameworkProductNames.NetMicroFramework;
94+
case FrameworkConstants.FrameworkIdentifiers.WindowsPhoneApp:
95+
case FrameworkConstants.FrameworkIdentifiers.WindowsPhone:
96+
return FrameworkProductNames.WindowsPhone;
97+
case FrameworkConstants.FrameworkIdentifiers.NetCore:
98+
if (framework.Version == FrameworkConstants.Version5)
99+
{
100+
return FrameworkProductNames.UWP;
101+
}
102+
103+
if (WindowsStoreNetCoreVersions.Contains(framework.Version))
104+
{
105+
return FrameworkProductNames.WindowsStore;
106+
}
107+
108+
return FrameworkConstants.FrameworkIdentifiers.NetCore;
109+
case FrameworkConstants.FrameworkIdentifiers.Windows:
110+
if (WindowsStoreWindowsVersions.Contains(framework.Version))
111+
{
112+
return FrameworkProductNames.WindowsStore;
113+
}
114+
return FrameworkConstants.FrameworkIdentifiers.Windows;
115+
case FrameworkConstants.FrameworkIdentifiers.UAP:
116+
return FrameworkProductNames.UWP;
117+
}
118+
119+
return framework.Framework;
120+
}
121+
122+
private PackageFrameworkCompatibilityBadges CreateFrameworkCompatibilityBadges(IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> table)
123+
{
124+
var net = GetBadgeFramework(table, FrameworkProductNames.Net);
125+
var netCore = GetBadgeFramework(table, FrameworkProductNames.NetCore);
126+
var netStandard = GetBadgeFramework(table, FrameworkProductNames.NetStandard);
127+
var netFramework = GetBadgeFramework(table, FrameworkProductNames.NetFramework);
128+
129+
return new PackageFrameworkCompatibilityBadges
130+
{
131+
Net = net,
132+
NetCore = netCore,
133+
NetStandard = netStandard,
134+
NetFramework = netFramework
135+
};
136+
}
137+
138+
private NuGetFramework GetBadgeFramework(IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> table, string productName)
139+
{
140+
if (table.TryGetValue(productName, out var data))
141+
{
142+
return data
143+
.Where(d => !d.IsComputed)
144+
.Select(d => d.Framework)
145+
.FirstOrDefault();
146+
}
147+
148+
return null;
149+
}
150+
}
151+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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 NuGet.Frameworks;
5+
6+
namespace NuGetGallery.Frameworks
7+
{
8+
public class PackageFrameworkCompatibilityTableData
9+
{
10+
/// <summary>
11+
/// Compatible framework.
12+
/// </summary>
13+
public NuGetFramework Framework { get; set; }
14+
15+
/// <summary>
16+
/// <see langword="true"/> if the <see cref="Framework"/> was computed from <see cref="IFrameworkCompatibilityService"/>.<br></br>
17+
/// <see langword="false"/> if the <see cref="Framework"/> was retrieved from the package asset frameworks.
18+
/// </summary>
19+
public bool IsComputed { get; set; }
20+
}
21+
}

src/NuGetGallery.Core/Frameworks/SupportedFrameworks.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ public static class SupportedFrameworks
2424
public static readonly NuGetFramework MonoTouch = new NuGetFramework(FrameworkIdentifiers.MonoTouch, EmptyVersion);
2525
public static readonly NuGetFramework MonoMac = new NuGetFramework(FrameworkIdentifiers.MonoMac, EmptyVersion);
2626
public static readonly NuGetFramework Net48 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 8, 0, 0));
27-
public static readonly NuGetFramework Net50Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version5, "windows");
28-
public static readonly NuGetFramework Net60Android = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "android");
29-
public static readonly NuGetFramework Net60Ios = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "ios");
30-
public static readonly NuGetFramework Net60MacOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "macos");
31-
public static readonly NuGetFramework Net60MacCatalyst = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "maccatalyst");
32-
public static readonly NuGetFramework Net60Tizen = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tizen");
33-
public static readonly NuGetFramework Net60TvOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tvos");
34-
public static readonly NuGetFramework Net60Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "windows");
27+
public static readonly NuGetFramework Net50Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version5, "windows", EmptyVersion);
28+
public static readonly NuGetFramework Net60Android = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "android", EmptyVersion);
29+
public static readonly NuGetFramework Net60Ios = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "ios", EmptyVersion);
30+
public static readonly NuGetFramework Net60MacOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "macos", EmptyVersion);
31+
public static readonly NuGetFramework Net60MacCatalyst = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "maccatalyst", EmptyVersion);
32+
public static readonly NuGetFramework Net60Tizen = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tizen", EmptyVersion);
33+
public static readonly NuGetFramework Net60TvOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tvos", EmptyVersion);
34+
public static readonly NuGetFramework Net60Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "windows", EmptyVersion);
3535
public static readonly NuGetFramework NetCore = new NuGetFramework(FrameworkIdentifiers.NetCore, EmptyVersion);
3636
public static readonly NuGetFramework NetMf = new NuGetFramework(FrameworkIdentifiers.NetMicro, EmptyVersion);
3737
public static readonly NuGetFramework UAP = new NuGetFramework(FrameworkIdentifiers.UAP, EmptyVersion);

tests/NuGetGallery.Core.Facts/Frameworks/FrameworkCompatibilityServiceFacts.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,19 @@ public void EmptyPackageFrameworksReturnsEmptySet()
3030
{
3131
var result = _service.GetCompatibleFrameworks(new List<NuGetFramework>());
3232

33-
Assert.Equal(expected: 0, actual: result.Count);
33+
Assert.Empty(result);
3434
}
3535

3636
[Fact]
37-
public void UnknownSupportedPackageReturnsEmptySet()
37+
public void UnknownSupportedPackageReturnsSetWithSameFramework()
3838
{
39-
var framework = NuGetFramework.Parse("netstandard9.2");
39+
var framework = NuGetFramework.Parse("net45-client");
4040
var frameworks = new List<NuGetFramework>() { framework };
4141
var compatible = _service.GetCompatibleFrameworks(frameworks);
4242

4343
Assert.False(framework.IsUnsupported);
44-
Assert.Equal(expected: 0, compatible.Count);
44+
Assert.Equal(expected: 1, compatible.Count);
45+
Assert.Contains(framework, compatible);
4546
}
4647

4748
[Theory]

0 commit comments

Comments
 (0)