-
Notifications
You must be signed in to change notification settings - Fork 253
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
[Feature]: Add option to allow versions of transitive dependencies to be overridden #10389
Comments
@marcin-krystianc, this is our current plan. The actual implementation may be a little rough as we get the pieces in place, but we're working on it. 👍 |
Throwing my vote on this too, hoping to see the priority bumped up. Honestly, I don't know where else to file it, but PackageReference has been completely unusable in my team's repo for the last several years due to the complex (and disorganized) nature of our dependencies. CPVM with transitive dependencies was our hope to finally make the move back to standardized tooling for our dependency management in a way that would not be grossly inconvenient for our developers. For context, my team depends on several components coming from several other teams each in their own repos which all publish to a variety of feeds (our upstream list is impressive). This results in a lot of complex dependency conflicts. The options to resolve those are to: We've been living with (c) for a very long time, but it's a recurring tax to maintain and doesn't work with any .NET tooling features. I've already spent over a week of time trying to move to PackageReference with CPVM on the basis that it would solve our transitive version problems (because that's how the CPVM spec reads). Having transitive pinning removed explains a lot of the difficulties I've been encountering. |
I have updated from Visual Studio 2019 16.8 to 16.9 (released this week) and transitive pinning doesn't seem to work anymore and lot of stuff broke just by updating VS on developers' machines (because the version of the MSBuild, which contains NuGet changes). @cristinamanum Was the transitive pinning disable rolled out as part of Visual Studio 16.9? The main issue for us is that the projects in solution that reference a package directly get one version, and projects that reference a package indirectly get different version, which results in package downgrades and we're back in the dependency hell... And that is even though the version is fixed in Directory.Packages.props. Also note that the documentation still doesn't reflect the changes, the docs still say that the transitive dependencies are pinned: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions If you have some, thanks for any information or links on the topic, it's a bit difficult to find up-to-date info... Anyway, transitive dependency pinning is a great feature, and one of the main reasons why we adopted CPVM. So it would be awesome to have it opt-in. |
Hi @rconard, are you actively working on bringing back the transitive pinning and making it opt-in feature ? If not, I'll start working on it next week. Any guidance on the implementation details will be very appreciated. |
@marcin-krystianc The NuGet team currently has other work as a higher priority, so we're not actively working on CPVM at this time. As for guidance, I assume that the opt-in will be at a per-project level. Our msbuild property gathering and reading is spread across NuGet.targets and MSBuildStaticGraphRestore. Once the work here is done, we'll also need to create a PR on the dotnet/project-system to tell it to pass through any new properties in Visual Studio. But only do that when the PR for NuGet is done, or very, very close to done and we're certain we're not going to rename the msbuild property. The PR you linked shows where the transitive dependencies code was Otherwise, I don't have any special insights/guidance. If anyone thinks that maybe there should be a nuget.config setting, rather than a per-project setting, then we probably need a design spec to discuss the various options and decide before wasting too much time on an implementation that gets partially thrown away if we decide to go down another route. A nuget.config setting would make the implementaton significantly easier (and avoid needing a PR on project-system). But I'm not sure if transitive pinning makes sense as a per-project setting, or a nuget.config setting, or both. Maybe this needs customer development and therefore PM work, and therefore shouldn't have any implementation started until we've decided how the opt-in should work. Maybe we do need a design spec first. |
@zivkan Why were the changes made in the first place? |
The discussion is in #10115. As you can see, the people who dislike the functionality are not Microsoft employees. |
@batzen I think that without transitive dependency pinning, CPVM essentially becomes just a very simple cosmetic feature, just like syntactic sugar. It's just to save you repeating the version number in many places. It's still a little bit useful, but not very much. It's the transitive dependency pinning that actually solved a difficult problem, and that is to get the versions of the dependencies under control and get out of the dependency hell in complex many-project solutions. Without transitive dependency pinning, you do actually use different versions of packages in different projects. For example, your test projects might end up using a different version of a library, because some direct dependency is missing somewhere in the chain (basically you can be testing something different than what you're running)... Transitive dependency pinning simplifies dependency management greatly for large complex solutions. It makes it much less fragile. With it, when someone adds a single But some library authors didn't like that it changed the dependency surface of their libraries, and so it was disabled entirely without a way to opt-in, and now no one can have the nice things. 😞 I believe CPVM is the most useful for really large solutions with many projects, and that it's much more useful for applications than for libraries. And that's because applications need to have the runtime binding redirects set up correctly, and you actually have full control over the dependencies. For libraries, it's still the consumer of the library who has the full control, so the transitive dependency pinning isn't that useful. You can set it up in some way, but depending on the consumer of the library, the actual dependency graphs and assemblies that end up in runtime might look completely different. I believe the decision to disable transitive dependency pinning entirely without providing an opt-in was a rushed decision and also a wrong decision to make. Just because transitive dependency pinning isn't a perfect fit for library authors, doesn't mean that it's not useful anywhere. That's why I'd love to see a comeback of that feature. And from what I read in these threads about CPVM, many other people actually do find it useful as well. |
Whole-heartedly agree with @tompazourek. Transitive pinning is the hugely appealing for managing dependencies; without it, trying to micro-manage dependency versions eventually leads to adding layers of transitive dependencies as primary references, which is little better than packages.config. If it's just pinning primary reference versions, that problem was already solved a number of ways (maybe less aesthetically pleasing than the Directory.Packages.props file, but solved nonetheless). |
…ncludeAssets reverts: NuGet#3719 Issue: NuGet/Home#10389
I've finally made the change to bring the transitive dependency feature back, go to NuGet/NuGet.Client#4025 for more details |
As long as it's optional that's fine. |
Hi friends, We're getting closer to finalized PRs for both version overrides and optional transitive pinning. We'd really appreciate any last comments on the following proposal before we merge it as it has some limitations you all may be aware of for transitive pinning scenarios. |
Does that wording mean transitive pinning is off by default? |
it means that people that voted against as part of the community will be able to have a choice. This is a win/win. What would be the concern that it serves more people ? |
2022 and pinning deps is still controversial in .NET. 😂 |
That was also my first knee-jerk reaction and had me scratching my head a bit ... but if you read the proposal, it talks about an opt-in to override the central version (via |
There's another question that bothers me for a long time. Is there a way to know the top-level dependencies from "packages. config"? |
Recently we've noticed a PR that disables the transitive pinning behaviour for CPVM.
It worries us because we started to rely on that feature (or rather on the unintentional side effect of that feature).
So the problem we are struggling with is the slowness of the restore operation. For large solutions that contain many projects and reference many packages the time needed for restore operation becomes unacceptable (see #10030 for details). As it is explained in the linked issue, the slowness is caused by the exponential nature of the graph walking algorithm.
We've discovered that enabling the CPVM for such solutions makes it to restore much quicker. It turns out that transitive pinning helps to reduce the impact of exponential nature of the graph walking algorithm. Because of the transitive pinning the graph walking needs to traverse the dependency graph of each centrally managed package only once. It happens only when a package node is visited from the top level node and it is skipped when visited from all other nodes (due to the "Nearest wins" rule).
I know that transitive pinning is a controversial feature. Some users want it but others really don't. But do you consider bringing it back and making it an opt-in feature as it was suggested in the comments of #10115 ? It is really important for us, so I'm happy to work on making this change if you are willing to accept it.
The text was updated successfully, but these errors were encountered: