diff --git a/pkgs/build-support/dotnet/build-dotnet-module/default.nix b/pkgs/build-support/dotnet/build-dotnet-module/default.nix index d3561282d3f..344a7acccc6 100644 --- a/pkgs/build-support/dotnet/build-dotnet-module/default.nix +++ b/pkgs/build-support/dotnet/build-dotnet-module/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenvNoCC, linkFarmFromDrvs, callPackage, nuget-to-nix, writeScript, makeWrapper, fetchurl, xml2, dotnetCorePackages, dotnetPackages, cacert }: +{ lib, stdenvNoCC, linkFarmFromDrvs, callPackage, nuget-to-nix, writeScript, makeWrapper, fetchurl, xml2, dotnetCorePackages, dotnetPackages, mkNugetSource, mkNugetDeps, cacert }: { name ? "${args.pname}-${args.version}" , pname ? name @@ -74,40 +74,13 @@ let inherit dotnet-sdk dotnet-test-sdk disabledTests nuget-source dotnet-runtime runtimeDeps buildType; }) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook; - _nugetDeps = linkFarmFromDrvs "${name}-nuget-deps" (import nugetDeps { - fetchNuGet = { pname, version, sha256 }: fetchurl { - name = "${pname}-${version}.nupkg"; - url = "https://www.nuget.org/api/v2/package/${pname}/${version}"; - inherit sha256; - }; - }); + _nugetDeps = mkNugetDeps { name = "${name}-nuget-deps"; nugetDeps = import nugetDeps; }; _localDeps = linkFarmFromDrvs "${name}-local-nuget-deps" projectReferences; - nuget-source = stdenvNoCC.mkDerivation rec { - name = "${pname}-nuget-source"; - meta.description = "A Nuget source with the dependencies for ${pname}"; - - nativeBuildInputs = [ dotnetPackages.Nuget xml2 ]; - buildCommand = '' - export HOME=$(mktemp -d) - mkdir -p $out/{lib,share} - - nuget sources Add -Name nixos -Source "$out/lib" - nuget init "${_nugetDeps}" "$out/lib" - ${lib.optionalString (projectReferences != []) - "nuget init \"${_localDeps}\" \"$out/lib\""} - - # Generates a list of all unique licenses' spdx ids. - find "$out/lib" -name "*.nuspec" -exec sh -c \ - "xml2 < {} | grep "license=" | cut -d'=' -f2" \; | sort -u > $out/share/licenses - ''; - } // { # This is done because we need data from `$out` for `meta`. We have to use overrides as to not hit infinite recursion. - meta.licence = let - depLicenses = lib.splitString "\n" (builtins.readFile "${nuget-source}/share/licenses"); - getLicence = spdx: lib.filter (license: license.spdxId or null == spdx) (builtins.attrValues lib.licenses); - in (lib.flatten (lib.forEach depLicenses (spdx: - if (getLicence spdx) != [] then (getLicence spdx) else [] ++ lib.optional (spdx != "") spdx - ))); + nuget-source = mkNugetSource { + name = "${args.pname}-nuget-source"; + description = "A Nuget source with the dependencies for ${args.pname}"; + deps = [ _nugetDeps _localDeps ]; }; in stdenvNoCC.mkDerivation (args // { diff --git a/pkgs/build-support/dotnet/make-nuget-deps/default.nix b/pkgs/build-support/dotnet/make-nuget-deps/default.nix new file mode 100644 index 00000000000..75178d5b779 --- /dev/null +++ b/pkgs/build-support/dotnet/make-nuget-deps/default.nix @@ -0,0 +1,9 @@ +{ linkFarmFromDrvs, fetchurl }: +{ name, nugetDeps }: + linkFarmFromDrvs "${name}-nuget-deps" (nugetDeps { + fetchNuGet = { pname, version, sha256 }: fetchurl { + name = "${pname}-${version}.nupkg"; + url = "https://www.nuget.org/api/v2/package/${pname}/${version}"; + inherit sha256; + }; + }) diff --git a/pkgs/build-support/dotnet/make-nuget-source/default.nix b/pkgs/build-support/dotnet/make-nuget-source/default.nix new file mode 100644 index 00000000000..0690a05aa2b --- /dev/null +++ b/pkgs/build-support/dotnet/make-nuget-source/default.nix @@ -0,0 +1,30 @@ +{ dotnetPackages, lib, xml2, stdenvNoCC }: +{ name, description ? "", deps ? [] }: +let + _nuget-source = stdenvNoCC.mkDerivation rec { + inherit name; + meta.description = description; + + nativeBuildInputs = [ dotnetPackages.Nuget xml2 ]; + buildCommand = '' + export HOME=$(mktemp -d) + mkdir -p $out/{lib,share} + + nuget sources Add -Name nixos -Source "$out/lib" + ${ lib.concatMapStringsSep "\n" (dep: + ''nuget init "${dep}" "$out/lib"'' + ) deps } + + # Generates a list of all unique licenses' spdx ids. + find "$out/lib" -name "*.nuspec" -exec sh -c \ + "xml2 < {} | grep "license=" | cut -d'=' -f2" \; | sort -u > $out/share/licenses + ''; +} // { # This is done because we need data from `$out` for `meta`. We have to use overrides as to not hit infinite recursion. + meta.licence = let + depLicenses = lib.splitString "\n" (builtins.readFile "${_nuget-source}/share/licenses"); + getLicence = spdx: lib.filter (license: license.spdxId or null == spdx) (builtins.attrValues lib.licenses); + in (lib.flatten (lib.forEach depLicenses (spdx: + if (getLicence spdx) != [] then (getLicence spdx) else [] ++ lib.optional (spdx != "") spdx + ))); +}; +in _nuget-source diff --git a/pkgs/build-support/writers/default.nix b/pkgs/build-support/writers/default.nix index 30301e3b2e5..0fb9bd939a5 100644 --- a/pkgs/build-support/writers/default.nix +++ b/pkgs/build-support/writers/default.nix @@ -1,4 +1,4 @@ -{ pkgs, config, buildPackages, lib, stdenv, libiconv, gawk, gnused, gixy }: +{ pkgs, config, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gawk, gnused, gixy }: let aliases = if (config.allowAliases or true) then (import ./aliases.nix lib) else prev: {}; @@ -301,6 +301,42 @@ let writePyPy3Bin = name: writePyPy3 "/bin/${name}"; + + makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath: + let + fname = last (builtins.split "/" nameOrPath); + path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx"; + _nugetDeps = mkNugetDeps { name = "${fname}-nuget-deps"; nugetDeps = libraries; }; + + nuget-source = mkNugetSource { + name = "${fname}-nuget-source"; + description = "A Nuget source with the dependencies for ${fname}"; + deps = [ _nugetDeps ]; + }; + + fsi = writeBash "fsi" '' + export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + export DOTNET_NOLOGO=1 + script="$1"; shift + ${dotnet-sdk}/bin/dotnet fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script" + ''; + + in content: writers.makeScriptWriter { + interpreter = fsi; + } path + '' + #i "nuget: ${nuget-source}/lib" + ${ content } + exit 0 + ''; + + writeFSharp = + makeFSharpWriter {}; + + writeFSharpBin = name: + writeFSharp "/bin/${name}"; + }; in writers // (aliases writers) diff --git a/pkgs/build-support/writers/test.nix b/pkgs/build-support/writers/test.nix index decd7e42d5c..d2e5cef83aa 100644 --- a/pkgs/build-support/writers/test.nix +++ b/pkgs/build-support/writers/test.nix @@ -150,6 +150,29 @@ let print(y[0]['test']) ''; + fsharp = makeFSharpWriter { + libraries = { fetchNuGet }: [ + (fetchNuGet { pname = "FSharp.SystemTextJson"; version = "0.17.4"; sha256 = "1bplzc9ybdqspii4q28l8gmfvzpkmgq5l1hlsiyg2h46w881lwg2"; }) + ]; + } "test-writers-fsharp" '' + #r "nuget: FSharp.SystemTextJson, 0.17.4" + + module Json = + open System.Text.Json + open System.Text.Json.Serialization + let options = JsonSerializerOptions() + options.Converters.Add(JsonFSharpConverter()) + let serialize<'a> (o: 'a) = JsonSerializer.Serialize<'a>(o, options) + let deserialize<'a> (str: string) = JsonSerializer.Deserialize<'a>(str, options) + + type Letter = A | B + let a = {| Hello = Some "World"; Letter = A |} + if a |> Json.serialize |> Json.deserialize |> (=) a + then "success" + else "failed" + |> printfn "%s" + ''; + pypy2NoLibs = writePyPy2 "test-writers-pypy2-no-libs" {} '' print("success") ''; @@ -161,6 +184,10 @@ let pypy3NoLibs = writePyPy3 "test-writers-pypy3-no-libs" {} '' print("success") ''; + + fsharpNoNugetDeps = writeFSharp "test-writers-fsharp-no-nuget-deps" '' + printfn "success" + ''; }; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e49e28257d1..6b24d121ed2 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -464,6 +464,8 @@ with pkgs; buildDotnetModule = callPackage ../build-support/dotnet/build-dotnet-module { }; nuget-to-nix = callPackage ../build-support/dotnet/nuget-to-nix { }; + mkNugetSource = callPackage ../build-support/dotnet/make-nuget-source { }; + mkNugetDeps = callPackage ../build-support/dotnet/make-nuget-deps { }; dotnetenv = callPackage ../build-support/dotnet/dotnetenv { dotnetfx = dotnetfx40;