NuGet / Home

Repo for NuGet Client issues
Other
1.49k stars 249 forks source link

Provide a way to use CPM in an incremental mode #12768

Open JonDouglas opened 11 months ago

JonDouglas commented 11 months ago

NuGet Product(s) Involved

Visual Studio Package Management UI, MSBuild.exe, dotnet.exe, NuGet SDK

The Elevator Pitch

For complex repositories that would like to adopt CPM, today it is all-or-nothing. The elevator pitch would be to have some type of "incremental" mode in which CPM can be respected by those packages that onboard a <PackageVersion> and lack Version in their <PackageReference>.

Perhaps a new mode such as <ManagePackageVersionsCentrallyMode> could have an incremental parameter or similar?

Additional Context and Details

No response

turbodrubin commented 11 months ago

See also #12316 for a previous request for this functionality from the community.

zivkan commented 11 months ago

For complex repositories that would like to adopt CPM, today it is all-or-nothing

This isn't technically/pedentically true. A single project is all-or-nothing, but anyone is free to (ab)use MSBuild to enable/disable CPM on specific projects, parts of a directory tree, etc. But it requires someone to understand MSBuild's scripting language and hand edit the files appropriately. Though as far as MSBuild goes, the knowledge required is fairly basic (look at the docs for "well known properties" and the docs on conditions, and/or the docs on multi-level merging of directory.build.props&tarets files; the same info applies to directory.packages.props)

JonDouglas commented 11 months ago

For more specifics, some SDKs such as Microsoft.NET.Test.SDK and the MAUI SDK are trying to use CPM. This is difficult for them today and for consumers using these SDKs because of all the implicit <PackageReference> that only SDK owners can really control.

This would also be a similar case for NuGet packages, SDKs, or libraries that make use of MSBuild targets/tasks to do similar mechanisms.

It would be nice for both SDK owners and SDK consumers to be able to incrementally use CPM rather than having to know deep MSBuild knowledge just to use the feature. That's a huge gap today in understanding.

dotMorten commented 7 months ago

My example: I maintain a set of class libraries. I want the class libraries to use lowest-necessary version, so users can choose any version from that and up. However in my test/sample apps, I might want to use newer versions to better test the range, so want a different version there. For example I might build a class library with Microsoft.WindowsAppSDK v1.0.0, but in my unit tests and sample apps, I want to use the latest version since they rely on newer functionality as well. I've also found that implicit referenced libraries gets confused, like .NET MAUI wants to use WindowsAppSDK v1.3 as minimum in the sample app, but you might want to use 1.0 in the class library you're building/shipping.

But at the end of the day, there's just a small subset of nuget packages that every single project reference, and they should all be the same version - those are the ones I want to manage centrally - the rest I want to just manage in each project head.

So what I'd like to see:

craigktreasure commented 7 months ago

This might deserve a separate issue, but I'd also like to add that it would be nice to be able to enable Transitive Pinning incrementally. For some large repos, it can be difficult to get all packages in a state where there are no conflicts. You can selectively enable it in certain parts of the tree (using Directory.Build.props for example), but it gets challenging when you have a lot of shared libraries.

This would be incredibly useful when addressing vulnerabilities in common packages like System.Drawing.Common or Newtonsoft.Json.

Something like the following would be extremely time saving and would prevent us from having to sprinkle direct dependencies all over to upgrade transitive dependencies:

<PackageVersion Include="System.Drawing.Common" Version="5.0.3" PinTransitively="true" />
rayao commented 1 week ago

Comparing to centralized package management, I think a "centralized package version override" feature would be more useful. Centralized package management forces PackageReference to remove Version attribute, the conversion is a tedious work, and most time (at least for my team) we just want a very limited set of dependencies to be managed, and the reason is in most time for security patch enforcement. I'm not sure if my request is same as @craigktreasure's above, I'd suggest a "forced version override" mode, which doesn't require removal of Version attribute in project files, just simply pin a package to some version (if not opt-out by project file).

zivkan commented 4 days ago

overrides already exist: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#overriding-package-versions