Add writeFSharp and makeFSharpWriter functions to writers

Uses fsharp interactive (fsi) to run fsx script

Expose mkNugetSource and mkNugetDeps functions

Use them in writers.writeFSharp and buildDotnetModule

Add tests
This commit is contained in:
Moises Nessim 2022-02-28 17:40:43 -05:00
parent b007a4e702
commit 81998d0a1d
6 changed files with 111 additions and 34 deletions

View file

@ -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 // {

View file

@ -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;
};
})

View file

@ -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

View file

@ -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)

View file

@ -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"
'';
};

View file

@ -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;