nix-community / dream2nix

Simplified nix packaging for various programming language ecosystems [maintainer=@DavHau]
https://dream2nix.dev
MIT License
1.01k stars 124 forks source link

Language request: dotnet #288

Open delneg opened 2 years ago

delneg commented 2 years ago

Currently, using dotnet languages (F# / C# / VB) is pretty straightforward starting with around dotnet core 3.1 (after it came 5.0, then 6.0, and 7.0 comes out november 2022) The basic process is written here but basically there are 3 steps:

  1. do dotnet restore for your .sln (or all .*proj files) to a specific folder, i.e. dotnet restore Foo.sln --packages ./nuget_tmp
  2. run dotnet-to-nix on this folder, i.e. nuget-to-nix ./nuget_tmp > deps.nix
  3. use nix function buildDotnetModule

Some examples: https://github.com/NixOS/nixpkgs/tree/master/pkgs/tools/misc/depotdownloader https://github.com/NixOS/nixpkgs/tree/master/pkgs/tools/backup/discordchatexporter-cli https://github.com/NixOS/nixpkgs/tree/master/pkgs/servers/jackett

bezmuth commented 2 years ago

Looks like some dotnet packages come with a package.lock.json in the source tree (https://github.com/baracoder/dotnet2nix/blob/master/src/dotnet2nix/packages.lock.json) with this and fetchNuGet+buildDotnetModule a pure translator could possibly be implemented (without dotnet2nix).

DavHau commented 2 years ago

A pure translator for packages.lock.json sounds like a great idea.

What hash algo is used for contentHash in packages.lock.json? It could be sha512, but I'm not sure. For a pure translator it is necessary that nix can understand the hashing algo.

bezmuth commented 2 years ago

Yes its sha512, the builtin fetchNuGet in nixpkgs is currently missing support for sha512/sri hashes so I've submitted a pull to fix that, for now I've just been using a dodgy custom version.

IvarWithoutBones commented 2 years ago

IIRC contentHash cannot be used as it is calculated in the middle of the nuget install procedure, the hash of the file you fetch will differentiate from it.

Another thing to keep in mind is that sometimes the packages.lock.json contains floating version numbers, not a whole lot of packages do that but an error should probably be thrown if detected.

I'm also not sure what this issue is asking for exactly, nuget-to-nix already exists which converts a nuget packages directory to a nix-based lockfile. I'm not familiar with this project, let me know if I'm missing something obvious here 😅

delneg commented 2 years ago

IIRC contentHash cannot be used as it is calculated in the middle of the nuget install procedure, the hash of the file you fetch will differentiate from it.

Another thing to keep in mind is that sometimes the packages.lock.json contains floating version numbers, not a whole lot of packages do that but an error should probably be thrown if detected.

I'm also not sure what this issue is asking for exactly, nuget-to-nix already exists which converts a nuget packages directory to a nix-based lockfile. I'm not familiar with this project, let me know if I'm missing something obvious here 😅

That's exactly why I mentioned packaging that way in the original message. Currently, I believe that nuget-to-nix packing is the most reliable way of getting it to work

DavHau commented 2 years ago

IIRC contentHash cannot be used as it is calculated in the middle of the nuget install procedure, the hash of the file you fetch will differentiate from it.

Whatever happens until the the middle of nuget install could possibly be reproduced via a fixed output derivation. Nix doesn't necessarily require the hash being calculated directly on the file. We can execute an arbitrary procedure on the file before hashing.

mdarocha commented 1 year ago

I made https://github.com/mdarocha/nuget-packageslock2nix, which I use pretty successfully to download NuGet depedendencies based on lock files.

The flake above is a drop-in to buildDotnetModule, but can be adapted to other projects, the logic itself is pretty simple :)

It all boils down to removing the signature file from the downloaded zip (nugets are just zips with another extension) during fetching.

It won't however handle more edge-cases, like non-nuget.org sources - packages.lock.json doesn't have enough metadata for that.