Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert "[TFM Display] Create model for badges and table from compatible frameworks. (#8881)"" #8927

Merged
merged 1 commit into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public ISet<NuGetFramework> GetCompatibleFrameworks(IEnumerable<NuGetFramework>
{
allCompatibleFrameworks.UnionWith(compatibleFrameworks);
}
else
{
allCompatibleFrameworks.Add(packageFramework);
}
}

return allCompatibleFrameworks;
Expand Down
17 changes: 17 additions & 0 deletions src/NuGetGallery.Core/Frameworks/FrameworkProductNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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.

namespace NuGetGallery.Frameworks
{
public static class FrameworkProductNames
{
public const string Net = ".NET";
public const string NetCore = ".NET Core";
public const string NetStandard = ".NET Standard";
public const string NetFramework = ".NET Framework";
public const string NetMicroFramework = ".NET Micro Framework";
public const string UWP = "Universal Windows Platform";
public const string WindowsPhone = "Windows Phone";
public const string WindowsStore = "Windows Store";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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 NuGet.Frameworks;
using System.Collections.Generic;

namespace NuGetGallery.Frameworks
{
public class PackageFrameworkCompatibility
{
/// <summary>
/// Contains a <see cref="NuGetFramework"/> for each of the .NET product (.NET, .NET Core, .NET Standard, and .NET Framework).
/// </summary>
public PackageFrameworkCompatibilityBadges Badges { get; set; }

/// <summary>
/// Contains a dictionary filled with all the package asset frameworks and all the computed compatible frameworks retrieved from <see cref="FrameworkCompatibilityService"/>.<br></br>
/// </summary>
/// <remarks>
/// Key: Is the <see cref="FrameworkProductNames"/> if resolved on (<seealso cref="PackageFrameworkCompatibilityFactory.ResolveFrameworkProductName(NuGetFramework)"/>) or the <see cref="NuGetFramework.Framework"/>.<br></br>
/// Value: Is an ordered collection containing all the compatible frameworks.
/// </remarks>
public IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> Table { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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 NuGet.Frameworks;

namespace NuGetGallery.Frameworks
{
/// <summary>
/// Contains a <see cref="NuGetFramework"/> for each of the .NET product (.NET, .NET Core, .NET Standard, and .NET Framework).
/// </summary>
/// <remarks>
/// All these properties are retrieved from the <see cref="PackageFrameworkCompatibility.Table"/>, one for each .NET product.<br></br>
/// Only package asset frameworks are considered. i.e. <see cref="PackageFrameworkCompatibilityTableData.IsComputed"/> <c>= false</c>.<br></br>
/// If there are no package asset frameworks for a particular .NET product, then the value will be <c>null</c>.
/// </remarks>
public class PackageFrameworkCompatibilityBadges
{
public NuGetFramework Net { get; set; }
public NuGetFramework NetCore { get; set; }
public NuGetFramework NetStandard { get; set; }
public NuGetFramework NetFramework { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using NuGet.Frameworks;
using NuGet.Services.Entities;

namespace NuGetGallery.Frameworks
{
public class PackageFrameworkCompatibilityFactory
{
private readonly ISet<Version> WindowsStoreNetCoreVersions = new HashSet<Version> { FrameworkConstants.EmptyVersion, Version.Parse("4.5.0.0"), Version.Parse("4.5.1.0") };
private readonly ISet<Version> WindowsStoreWindowsVersions = new HashSet<Version> { FrameworkConstants.EmptyVersion, Version.Parse("8.0.0.0"), Version.Parse("8.1.0.0") };
private readonly NuGetFrameworkSorter Sorter = new NuGetFrameworkSorter();
private readonly int NetStartingMajorVersion = 5;

private readonly IFrameworkCompatibilityService _compatibilityService;

public PackageFrameworkCompatibilityFactory(IFrameworkCompatibilityService compatibilityService)
{
_compatibilityService = compatibilityService ?? throw new ArgumentNullException();
}

public PackageFrameworkCompatibility Create(ICollection<PackageFramework> packageFrameworks)
{
if (packageFrameworks == null)
{
throw new ArgumentNullException(nameof(packageFrameworks));
}

var filteredPackageFrameworks = packageFrameworks
.Select(pf => pf.FrameworkName)
.Where(f => !f.IsUnsupported && !f.IsPCL)
.ToHashSet();

var table = CreateFrameworkCompatibilityTable(filteredPackageFrameworks);
var badges = CreateFrameworkCompatibilityBadges(table);

return new PackageFrameworkCompatibility
{
Badges = badges,
Table = table
};
}

private IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> CreateFrameworkCompatibilityTable(ICollection<NuGetFramework> filteredPackageFrameworks)
{
var compatibleFrameworks = _compatibilityService.GetCompatibleFrameworks(filteredPackageFrameworks);

var table = new Dictionary<string, ICollection<PackageFrameworkCompatibilityTableData>>();

foreach (var compatibleFramework in compatibleFrameworks)
{
var productName = ResolveFrameworkProductName(compatibleFramework);
var data = new PackageFrameworkCompatibilityTableData
{
Framework = compatibleFramework,
IsComputed = !filteredPackageFrameworks.Contains(compatibleFramework)
};

if (table.TryGetValue(productName, out var allCompatibleFrameworks))
{
allCompatibleFrameworks.Add(data);
}
else
{
var newCompatibleFrameworks = new SortedSet<PackageFrameworkCompatibilityTableData>
(Comparer<PackageFrameworkCompatibilityTableData>.Create((a, b) => Sorter.Compare(a.Framework, b.Framework)));

newCompatibleFrameworks.Add(data);
table.Add(productName, newCompatibleFrameworks);
}
}

return table;
}

private string ResolveFrameworkProductName(NuGetFramework framework)
{
// See: https://docs.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-frameworks
switch (framework.Framework)
{
case FrameworkConstants.FrameworkIdentifiers.NetCoreApp:
return framework.Version.Major >= NetStartingMajorVersion ? FrameworkProductNames.Net : FrameworkProductNames.NetCore;
case FrameworkConstants.FrameworkIdentifiers.NetStandard:
case FrameworkConstants.FrameworkIdentifiers.NetStandardApp:
return FrameworkProductNames.NetStandard;
case FrameworkConstants.FrameworkIdentifiers.Net:
return FrameworkProductNames.NetFramework;
case FrameworkConstants.FrameworkIdentifiers.NetMicro:
return FrameworkProductNames.NetMicroFramework;
case FrameworkConstants.FrameworkIdentifiers.WindowsPhoneApp:
case FrameworkConstants.FrameworkIdentifiers.WindowsPhone:
return FrameworkProductNames.WindowsPhone;
case FrameworkConstants.FrameworkIdentifiers.NetCore:
if (framework.Version == FrameworkConstants.Version5)
{
return FrameworkProductNames.UWP;
}

if (WindowsStoreNetCoreVersions.Contains(framework.Version))
{
return FrameworkProductNames.WindowsStore;
}

return FrameworkConstants.FrameworkIdentifiers.NetCore;
case FrameworkConstants.FrameworkIdentifiers.Windows:
if (WindowsStoreWindowsVersions.Contains(framework.Version))
{
return FrameworkProductNames.WindowsStore;
}
return FrameworkConstants.FrameworkIdentifiers.Windows;
case FrameworkConstants.FrameworkIdentifiers.UAP:
return FrameworkProductNames.UWP;
}

return framework.Framework;
}

private PackageFrameworkCompatibilityBadges CreateFrameworkCompatibilityBadges(IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> table)
{
var net = GetBadgeFramework(table, FrameworkProductNames.Net);
var netCore = GetBadgeFramework(table, FrameworkProductNames.NetCore);
var netStandard = GetBadgeFramework(table, FrameworkProductNames.NetStandard);
var netFramework = GetBadgeFramework(table, FrameworkProductNames.NetFramework);

return new PackageFrameworkCompatibilityBadges
{
Net = net,
NetCore = netCore,
NetStandard = netStandard,
NetFramework = netFramework
};
}

private NuGetFramework GetBadgeFramework(IReadOnlyDictionary<string, ICollection<PackageFrameworkCompatibilityTableData>> table, string productName)
{
if (table.TryGetValue(productName, out var data))
{
return data
.Where(d => !d.IsComputed)
.Select(d => d.Framework)
.FirstOrDefault();
}

return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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 NuGet.Frameworks;

namespace NuGetGallery.Frameworks
{
public class PackageFrameworkCompatibilityTableData
{
/// <summary>
/// Compatible framework.
/// </summary>
public NuGetFramework Framework { get; set; }

/// <summary>
/// <see langword="true"/> if the <see cref="Framework"/> was computed from <see cref="IFrameworkCompatibilityService"/>.<br></br>
/// <see langword="false"/> if the <see cref="Framework"/> was retrieved from the package asset frameworks.
/// </summary>
public bool IsComputed { get; set; }
}
}
16 changes: 8 additions & 8 deletions src/NuGetGallery.Core/Frameworks/SupportedFrameworks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ public static class SupportedFrameworks
public static readonly NuGetFramework MonoTouch = new NuGetFramework(FrameworkIdentifiers.MonoTouch, EmptyVersion);
public static readonly NuGetFramework MonoMac = new NuGetFramework(FrameworkIdentifiers.MonoMac, EmptyVersion);
public static readonly NuGetFramework Net48 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 8, 0, 0));
public static readonly NuGetFramework Net50Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version5, "windows");
public static readonly NuGetFramework Net60Android = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "android");
public static readonly NuGetFramework Net60Ios = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "ios");
public static readonly NuGetFramework Net60MacOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "macos");
public static readonly NuGetFramework Net60MacCatalyst = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "maccatalyst");
public static readonly NuGetFramework Net60Tizen = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tizen");
public static readonly NuGetFramework Net60TvOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tvos");
public static readonly NuGetFramework Net60Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "windows");
public static readonly NuGetFramework Net50Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version5, "windows", EmptyVersion);
public static readonly NuGetFramework Net60Android = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "android", EmptyVersion);
public static readonly NuGetFramework Net60Ios = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "ios", EmptyVersion);
public static readonly NuGetFramework Net60MacOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "macos", EmptyVersion);
public static readonly NuGetFramework Net60MacCatalyst = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "maccatalyst", EmptyVersion);
public static readonly NuGetFramework Net60Tizen = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tizen", EmptyVersion);
public static readonly NuGetFramework Net60TvOs = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "tvos", EmptyVersion);
public static readonly NuGetFramework Net60Windows = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version6, "windows", EmptyVersion);
public static readonly NuGetFramework NetCore = new NuGetFramework(FrameworkIdentifiers.NetCore, EmptyVersion);
public static readonly NuGetFramework NetMf = new NuGetFramework(FrameworkIdentifiers.NetMicro, EmptyVersion);
public static readonly NuGetFramework UAP = new NuGetFramework(FrameworkIdentifiers.UAP, EmptyVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@ public void EmptyPackageFrameworksReturnsEmptySet()
{
var result = _service.GetCompatibleFrameworks(new List<NuGetFramework>());

Assert.Equal(expected: 0, actual: result.Count);
Assert.Empty(result);
}

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

Assert.False(framework.IsUnsupported);
Assert.Equal(expected: 0, compatible.Count);
Assert.Equal(expected: 1, compatible.Count);
Assert.Contains(framework, compatible);
}

[Theory]
Expand Down
Loading