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

According to DefaultCompatibilityProvider, net5.0-windows packages are not compatible with net5.0-windows projects #10897

Closed
ghelyar opened this issue May 27, 2021 · 2 comments
Labels
Resolution:NotABug This issue appears to not be a bug Resolution:Question This issues appears to be a question, not a product defect

Comments

@ghelyar
Copy link

ghelyar commented May 27, 2021

Details about Problem

NuGet product used (NuGet.exe | Visual Studio | MSBuild.exe | dotnet.exe):

NuGet.Protocol package.

Product version:

5.9.1

Repro steps and/or sample project

Create a net5.0-windows project and pack it into a NuGet package, then consume it from another net5.0-windows project.

The package is generated as net5.0-windows7.0

use DefaultCompatibilityProvider to check whether the package is compatible with the net5.0-windows target framework:

var projectFramework = NuGetFramework.Parse("net5.0-windows");
var packageFramework = NuGetFramework.Parse("net5.0-windows7.0");
var isCompatible = DefaultCompatibilityProvider.Instance.IsCompatible(projectFramework, packageFramework); // false

Expected output: true

Actual output: false

@nkolev92
Copy link
Member

TargetFramework values are just strings to NuGet.

When you specify net5.0-windows, the .NET SDK attaches a version to the target platform.

So when NuGet reads the relevant properties, TargetFrameworkMoniker and TargetPlatformMoniker, it gets .NETCoreApp,Version=v5.0 and Windows,Version=7.0.

For NuGet at restore/pack time, a target platform version is requires (such as 7.0), so NuGet really is comparing the compat between net5.0-windows7.0 and net5.0-windows7.0.

net5.0-windows itself translates to net5.0-windows0.0 in the framework APIs, which is why it's shown as incompatible.

https://github.com/dotnet/designs/blob/main/accepted/2020/net5/net5.md
https://devblogs.microsoft.com/dotnet/announcing-net-5-0/#net-5-0-target-framework

@nkolev92 nkolev92 added Resolution:NotABug This issue appears to not be a bug Resolution:Question This issues appears to be a question, not a product defect labels May 27, 2021
@ghelyar
Copy link
Author

ghelyar commented May 28, 2021

Yes, I can see how the code currently works, and it makes sense that 0.0 is not compatible with 7.0, in the same way that 7.0 would not be compatible with 8.0.

The problem is that there isn't a consistent default platform version. net5.0-windows is supposedly equivalent to net5.0-windows7.0, but this part of the system sets it to 0.0. Which is correct? net5.0-windows == net5.0-windows7.0 or net5.0-windows == net5.0-windows0.0?

I couldn't find any official documentation that said the default platform version of the windows platform should be 7.0, other than the linked github issue. The closest I could find was for runtime identifiers.

If net5.0-windows is equivalent to net5.0-windows7.0 then I can work around the problem by adding a framework mapping:

var compatibilityProvider = new CompatibilityProvider(
    new FrameworkNameProvider(new[] { DefaultFrameworkMappings.Instance, new CustomFrameworkMappings() },
    new[] { DefaultPortableFrameworkMappings.Instance }));

class CustomFrameworkMappings : IFrameworkMappings
{
    public IEnumerable<KeyValuePair<NuGetFramework, NuGetFramework>> EquivalentFrameworks =>
        new Dictionary<NuGetFramework, NuGetFramework> { { NuGetFramework.Parse("net5.0-windows"), NuGetFramework.Parse("net5.0-windows7.0") } };

    // other properties omitted - Enumerable.Empty<T> for all of them works.
}

but this approach has to add a new entry for every combination e.g. net6.0 would have to be added separately. It also doesn't work for checking whether net5.0-windows is compatible with net5.0-windows8.0 or above, although there may be some other mapping in here that is more flexible rather than EquivalentFrameworks.

If the default platform version for windows when omitted is always 7.0, then I can replace the empty platform version with 7.0

private static NuGetFramework AddDefaultPlatformVersion(NuGetFramework framework)
{
    if (framework.Platform == "windows" && framework.PlatformVersion == FrameworkConstants.EmptyVersion)
    {
        return new NuGetFramework(framework.Framework, framework.Version, framework.Platform, new Version(7, 0));
    }
    return framework;
}

But if net5.0-windows really is equivalent to net5.0-windows7.0, it would be nice if the package just handled this. Presumably the same problem exists for any platform, and there is also e.g. a default android platform version, a default ios platform version, etc when these nuget packages are created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution:NotABug This issue appears to not be a bug Resolution:Question This issues appears to be a question, not a product defect
Projects
None yet
Development

No branches or pull requests

2 participants