NuGet / Home

Repo for NuGet Client issues
Other
1.5k stars 252 forks source link

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

Open JonDouglas opened 1 year ago

JonDouglas commented 1 year 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 1 year ago

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

zivkan commented 1 year 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 1 year 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 12 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 12 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 5 months 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 months ago

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

jbennink commented 2 months ago

@dotMorten

  • Only manage packages defined in CPM, but allow other packages with version to be defined in project.

@rayao

Centralized package management forces PackageReference to remove Version attribute, the conversion is a tedious work

This is what had me stumped. You can't adopt CPM unless all projects remove the "Version" from the package reference. Why!!!! It would be much more usefull to have the CPM version always override the Version in the project, and also have a VersionOverride option in the project for cases where it is absolutely neceessary to have a specific version.

Now I am faced with a "solution" consisting of 100 projects that I have to go by everyone to remove versions beofre repaping any possible benefits.