Dependency resolution differences between .NET Core and Mono - project.assets.json apparently causing problems
Nobody has claimed this yet.
- Dominant language
- F#
- Stars
- 2.1k
- Forks
- 528
- Avg merge
- 1d 12m
- Merged PRs (30d)
- 54
Description
Description
The dependency resolution process in .NET Core appears to differ from what happens on Mono, which is causing problems with some packages (specifically in this case, the Suave.OAuth 0.9.0-pre2 package).
Repro steps
I don't yet know if this is reproducible on Windows, but I can reproduce this on Linux by the following method:
- Clone the https://github.com/fable-compiler/fable-suave-scaffold repo into a folder called
withdotnet. - While that clones, start a new Terminal tab or window. In the second tab, create an empty folder called
withmono, a sister folder towithdotnet. - In the
withmonoproject, create a new Suave project from the Forge Suave template (I used Ionide in VS Code and chose "New Project" from the menu, then picked the Suave template). Project foldersrc, project nameWithMono. - While Forge is busy creating the
withmonoproject, go to your first Terminal tab (in thewithdotnetfolder) and editpaket.dependencies. Addnuget Suave.OAuth prereleaseto the dependencies. (Suave.OAuth first started supporting .NET Core in 0.9.0, which as of this writing is still a prelease version. If Suave.OAuth 0.9.0 is released by the time you repro this, you can skip theprereleasepart of that line.) - Also edit
withmono/src/Server/paket.referencesand addSuave.OAuthto the references file. - Make sure you have .NET Core 1.0.4 installed (for Ubuntu, it's in the
dotnet-dev-1.0.4package). - Still in
withdotnet, runmono .paket/paket.exe installto make sure the Suave.OAuth NuGet package dependencies are resolved and thepaket.lockfile is updated. (The./build.shscript in the fable-suave-scaffold project just does arestore, not aninstall, so it will skip the Suave.OAuth package if you haven't done aninstall, and you won't trigger this bug). - Still in
withdotnet, run./build.sh. This will take a while, so switch back to the other Terminal tab now. - In
withmono, editpaket.dependenciesandsrc/WithMono/paket.referencesto addnuget Suave.OAuth prereleaseandSuave.Oauthrespectively, just as you did in thewithdotnetproject. - In
withmono, run.paket/paket.bootstrapper.exeto get Paket, then run.paket/paket.exe installto set up thepaket.lockfile. - In
withmono, run./build.sh. You should see it succeed. - Switch back to the
withdotnettab, which should have failed by now. Scroll up past the hundreds of "Error: ConnectFailure (Connection refused)" messages to find their cause: .NET Core is trying to load the Suave assembly version 2.0.0, but you have 2.1.1 (or later, depending on when you run this repro). See error message below:
Could not load file or assembly 'Suave, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
The root cause of this appears to be in the src/Server/obj/project.assets.json file, where Suave.OAuth is listed as having a dependency on Suave version 2.0.0. This comes from the Suave.OAuth.nuspec file, where the Suave dependency is indeed listed as being "2.0.0". However, the .nuspec specification says that a notation of "1.0" is the equivalent of "<= 1.0". But the behavior of project.assets.json appears to be different: the fact that project.assets.json lists Suave.OAuth as having a dependency on "Suave": "2.0.0" is the only place I can find where this dependency could be coming from.
Expected behavior
The Suave dependency of "2.0.0" should be treated as in the .nuspec file, and a Suave version of 2.1.1 should satisfy the dependency.
Actual behavior
Under Mono (and I presume under .Net Framework as well), the expected behavior is what I get. But under .Net Core, I cannot get this to work.
Known workarounds
The only workaround I've found so far is to explicitly list Suave 2.0.0 in paket.dependencies under .NET Core. This makes MSBuild happy, because the assembly that it's loading matches the one referenced. But I'm not happy, because Suave 2.1 includes at least one very important security fix. I can use Suave 2.0.0 while developing, but I can't deploy that version of Suave.
Another workaround that I tried, but that failed, was to edit the project.assets.json file by hand and change the "Suave": "2.0.0" line to "Suave": ">= 2.0.0". But this edit was overwritten by Paket when I re-ran ,/build.sh, so that didn't work.
This is probably ultimately caused by a bug in .NET Core, but I have no idea how to create a repro that they will accept.
Possibly-related issues: #2208, #2497, and maybe others. And this could also be a PEBKAC issue: I am still very confused by .NET Core and its build system. The reason I used the fable-suave-scaffold project in my repro above is because the only way I've (so far) succeeded in building anything under .NET Core was to clone fable-suave-scaffold and build it. So I don't actually know how to create a smaller repro project that will demonstrate this problem.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/Server/obj/project.assets.json and the Suave.OAuth.nuspec referenced in the report, then compare the fable-suave-scaffold build.sh flow under .NET Core and Mono. Check whether Paket generates the dependency entry or whether .NET Core interprets it differently; done means reproducing the mismatch and identifying a supported fix or a minimal report for the responsible component.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fsharp
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100