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

Support pinning NETStandard.Library in CPM. #13990

Closed
teo-tsirpanis opened this issue Dec 8, 2024 · 4 comments
Closed

Support pinning NETStandard.Library in CPM. #13990

teo-tsirpanis opened this issue Dec 8, 2024 · 4 comments

Comments

@teo-tsirpanis
Copy link

NuGet Product(s) Involved

Other/NA

The Elevator Pitch

I discovered that if you manually reference the latest version of NETStandard.Library while referencing a .NET Standard 1.x only package, the dozens of NS1's transitive dependencies disappear when your project targets a framework compatible with .NET Standard 2.0. However if you have Central Package Management enabled, pinning NETStandard.Library with PackageVersion is not possible and results in NU1009 errors.

It would be great if this was somehow allowed, and would enable getting rid of pinning to non-vulnerable packages brought by NS1.x, like what MSBuild has to do (1, 2).

Additional Context and Details

There are multiple ways of achieving this, ranging from just not failing when that library is pinned with PackageVersion, updating the meaning of the existing NetStandardImplicitPackageVersion property, up to automatically referencing a new version of the library in an opt-out fashion.

@Nigusu-Allehu
Copy link
Contributor

If your project is targeting .NET Standard, the NETStandard.Library package is implicitly referenced. This means there is no need to manually reference or pin the package. If you want to use a newer version of the framework, you can achieve this by changing the Target Framework Moniker (TFM) of your project. For example, updating the <TargetFramework> property in your project file to netstandard2.0 or a later version will implicitly use the appropriate NETStandard.Library version.

This is detailed in the error message, the NU1009.

Regarding your observation that this issue might be caused by referencing a package that depends solely on .NET Standard 1.x: are you certain it is not happening because your project itself is targeting .NET Standard? To confirm, try the following steps:

  1. Remove the netstandard1.x targetting package you mentioned from your project.
  2. Restore the project dependencies.
  3. Observe if the NU1009 error still occurs.

If the error persists, it is likely due to the project's target framework rather than the dependency. However, if removing the package resolves the error, then the issue lies with how the dependency interacts with the target framework and CPM.

@teo-tsirpanis
Copy link
Author

If my library is targeting .NET Standard the unnecessary transitive dependencies indeed go away, but that's not the case if I target .NET 8. Try restoring the following project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
  </PropertyGroup>
  <ItemGroup>
    <!-- NS1.x-only library -->
    <PackageReference Include="RuntimeContracts" Version="0.5.0" />
  </ItemGroup>
</Project>

On .NET 8 it has lots of dependencies, while on .NET Standard 2.0 it doesn't:

image

If I add <PackageReference Condition="'$(TargetFrameworkIdentifier)' != '.NETStandard'" Include="NETStandard.Library" Version="2.0.3" /> it fixes this problem:

image

But I can't manually select the version of NETStandard.Library in a non-.NET Standard project if CPM is enabled. I tried NetStandardImplicitPackageVersion but it has no effect.

@zivkan
Copy link
Member

zivkan commented Dec 17, 2024

NU1009 happens when CPM sees a PackageVersion on a PackageReference where IsImplicitlyDefined="true". If you put the same Condition (TFI != ".NETStandard") on thhe PackageVersion, then CPM won't see both at the same time. CPM not allowing a PackageVersion on packages that are defined implicitly is by design . MSBuild SDKs that define PackageReferences take responsibility for selecting the version.

The end goal you're trying to achieve, removing a bynch of System.* packages from the package graph, is going to solved by a feature called prune package references (initially called Supplied By Platform), whcih is under active development (and a pull request currently open implementing NuGet's side of the feature). So, I'm closing this issue as a duplicate of that one, as once pruned package references is available there won't be a need for any other workaround for the NETStandard.Library package.

@zivkan zivkan closed this as not planned Won't fix, can't repro, duplicate, stale Dec 17, 2024
@teo-tsirpanis
Copy link
Author

I tested your suggestion and it works, thanks! Looking forward to use prune package references.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants