fsprojects / Paket

A dependency manager for .NET with support for NuGet packages and Git repositories.
https://fsprojects.github.io/Paket/
MIT License
2k stars 520 forks source link

Net471 project: Paket pulls in netstandard2.0 dependency instead of net35 #3518

Open dbruning opened 5 years ago

dbruning commented 5 years ago

Description

I have created a repro here Basically it's a Framework v4.7.1 project pulling in 2 dependencies: xUnit and Jetbrains DotMemory

DotMemory has 2 libs: netstandard2.0 and net35

Paket is pulling in the netstandard2.0 library (see the .csproj file), whereas I would have expected it to pull in the net35 dependency.

How can I trace why Paket is choosing that library, and how can I force it to choose the net35 library instead?

matthid commented 5 years ago

How can I trace why Paket is choosing that library, and how can I force it to choose the net35 library instead?

Only by trying to understand this file. There is no real spec we followed we try to prefer stuff and give penalties for stuff we don't want: https://github.com/fsprojects/Paket/blob/master/src/Paket.Core/Versioning/PlatformMatching.fs Ideally we would follow the nuget spec (whatever that might be)

usually we prefer framework on framework dependencies but here it might have out-ruled something else, because from 4.7.1 to net3.5 there are a lot of versions in between?

matthid commented 5 years ago

And you should feel comfortable to replace/rewrite or edit this particular area as I think the test-coverage there is quite good.

dbruning commented 5 years ago

Thanks @matthid but I'm not the one you want rewriting that code - I don't know F# and my knowledge of the permutations of net frameworks / standard isn't deep.

I did find this website (linked to from Microsoft docs) which claims to find the nearest framework operation using Nuget's logic, and that one found net35.

The code behind that tool is MIT licensed, perhaps it would be possible to leverage that logic or re-implement the same logic in Paket?

jbaehr commented 5 years ago

We have a similar issue, I assume it has the same origins. (please tell me if not; then I'll create a dedicated issue)

We use the package System.IO.Abstractions (in v4.1.6, but that doesn't matter). It declares no dependencies for net40, and System.IO.FileSystem.AccessControl for netstandard20.

We used to target net452 so the only way out was to take the empty net40 dependency declaration an everything was fine. After the update to net472 paket has two options as both as net472 is compatible to both, net40 and netstandard20. Now things became weird: On half of our deveoper's machines paket takes the net40-route (no further depdencies), on the other half it tries to get AccessControl nuget required by the netstandard20 declaration (and fails as this spurious package is not available on our internal mirror).

In all cases paket-5.181.1 was used, on the machines that fail we could reproduce the failure with paket-5.207. As of now we haven't found what makes the one half of the machines different from the other. We have mixed win7 and win10 systems; with VS2015 and/or VS2017 installed.

ruhullahshah commented 5 years ago

Finding/Workaround

Upon running paket.exe clear-cache, Paket works as expected, taking the net40 route instead of netstandard20 for System.IO.Abstractions, when the framework restriction is set to net472 in paket.dependencies.

Methodology

We could not debug the issue further due to time & resource limitations. It would be nice to know the reason for this behavior. Maybe it is well-known among the maintainers already or there is some documentation for this.