diff --git a/pkgs/build-support/dotnet/build-dotnet-module/default.nix b/pkgs/build-support/dotnet/build-dotnet-module/default.nix index 470d2d47ff94..b321c8eb10c5 100644 --- a/pkgs/build-support/dotnet/build-dotnet-module/default.nix +++ b/pkgs/build-support/dotnet/build-dotnet-module/default.nix @@ -1,18 +1,18 @@ { lib , stdenvNoCC , callPackage +, writeShellScript +, writeText +, srcOnly , linkFarmFromDrvs +, symlinkJoin +, makeWrapper , dotnetCorePackages , dotnetPackages , mkNugetSource , mkNugetDeps -, srcOnly -, writeShellScript -, writeText -, makeWrapper , nuget-to-nix , cacert -, symlinkJoin , coreutils }: @@ -20,66 +20,67 @@ , pname ? name , enableParallelBuilding ? true , doCheck ? false -# Flags to pass to `makeWrapper`. This is done to avoid double wrapping. -, makeWrapperArgs ? [] + # Flags to pass to `makeWrapper`. This is done to avoid double wrapping. +, makeWrapperArgs ? [ ] -# Flags to pass to `dotnet restore`. -, dotnetRestoreFlags ? [] -# Flags to pass to `dotnet build`. -, dotnetBuildFlags ? [] -# Flags to pass to `dotnet test`, if running tests is enabled. -, dotnetTestFlags ? [] -# Flags to pass to `dotnet install`. -, dotnetInstallFlags ? [] -# Flags to pass to `dotnet pack`. -, dotnetPackFlags ? [] -# Flags to pass to dotnet in all phases. -, dotnetFlags ? [] + # Flags to pass to `dotnet restore`. +, dotnetRestoreFlags ? [ ] + # Flags to pass to `dotnet build`. +, dotnetBuildFlags ? [ ] + # Flags to pass to `dotnet test`, if running tests is enabled. +, dotnetTestFlags ? [ ] + # Flags to pass to `dotnet install`. +, dotnetInstallFlags ? [ ] + # Flags to pass to `dotnet pack`. +, dotnetPackFlags ? [ ] + # Flags to pass to dotnet in all phases. +, dotnetFlags ? [ ] -# The path to publish the project to. When unset, the directory "$out/lib/$pname" is used. + # The path to publish the project to. When unset, the directory "$out/lib/$pname" is used. , installPath ? null -# The binaries that should get installed to `$out/bin`, relative to `$out/lib/$pname/`. These get wrapped accordingly. -# Unfortunately, dotnet has no method for doing this automatically. -# If unset, all executables in the projects root will get installed. This may cause bloat! + # The binaries that should get installed to `$out/bin`, relative to `$out/lib/$pname/`. These get wrapped accordingly. + # Unfortunately, dotnet has no method for doing this automatically. + # If unset, all executables in the projects root will get installed. This may cause bloat! , executables ? null -# Packs a project as a `nupkg`, and installs it to `$out/share`. If set to `true`, the derivation can be used as a dependency for another dotnet project by adding it to `projectReferences`. + # Packs a project as a `nupkg`, and installs it to `$out/share`. If set to `true`, the derivation can be used as a dependency for another dotnet project by adding it to `projectReferences`. , packNupkg ? false -# The packages project file, which contains instructions on how to compile it. This can be an array of multiple project files as well. + # The packages project file, which contains instructions on how to compile it. This can be an array of multiple project files as well. , projectFile ? null -# The NuGet dependency file. This locks all NuGet dependency versions, as otherwise they cannot be deterministically fetched. -# This can be generated by running the `passthru.fetch-deps` script. + # The NuGet dependency file. This locks all NuGet dependency versions, as otherwise they cannot be deterministically fetched. + # This can be generated by running the `passthru.fetch-deps` script. , nugetDeps ? null -# A list of derivations containing nupkg packages for local project references. -# Referenced derivations can be built with `buildDotnetModule` with `packNupkg=true` flag. -# Since we are sharing them as nugets they must be added to csproj/fsproj files as `PackageReference` as well. -# For example, your project has a local dependency: -# -# To enable discovery through `projectReferences` you would need to add a line: -# -# -, projectReferences ? [] -# Libraries that need to be available at runtime should be passed through this. -# These get wrapped into `LD_LIBRARY_PATH`. -, runtimeDeps ? [] + # A list of derivations containing nupkg packages for local project references. + # Referenced derivations can be built with `buildDotnetModule` with `packNupkg=true` flag. + # Since we are sharing them as nugets they must be added to csproj/fsproj files as `PackageReference` as well. + # For example, your project has a local dependency: + # + # To enable discovery through `projectReferences` you would need to add a line: + # + # +, projectReferences ? [ ] + # Libraries that need to be available at runtime should be passed through this. + # These get wrapped into `LD_LIBRARY_PATH`. +, runtimeDeps ? [ ] -# Tests to disable. This gets passed to `dotnet test --filter "FullyQualifiedName!={}"`, to ensure compatibility with all frameworks. -# See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#filter-option-details for more details. -, disabledTests ? [] -# The project file to run unit tests against. This is usually referenced in the regular project file, but sometimes it needs to be manually set. -# It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this. + # Tests to disable. This gets passed to `dotnet test --filter "FullyQualifiedName!={}"`, to ensure compatibility with all frameworks. + # See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test#filter-option-details for more details. +, disabledTests ? [ ] + # The project file to run unit tests against. This is usually referenced in the regular project file, but sometimes it needs to be manually set. + # It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this. , testProjectFile ? "" -# The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc. + # The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc. , buildType ? "Release" -# If set to true, builds the application as a self-contained - removing the runtime dependency on dotnet + # If set to true, builds the application as a self-contained - removing the runtime dependency on dotnet , selfContainedBuild ? false -# The dotnet SDK to use. + # The dotnet SDK to use. , dotnet-sdk ? dotnetCorePackages.sdk_6_0 -# The dotnet runtime to use. + # The dotnet runtime to use. , dotnet-runtime ? dotnetCorePackages.runtime_6_0 -# The dotnet SDK to run tests against. This can differentiate from the SDK compiled against. + # The dotnet SDK to run tests against. This can differentiate from the SDK compiled against. , dotnet-test-sdk ? dotnet-sdk -, ... } @ args: +, ... +} @ args: assert projectFile == null -> throw "Defining the `projectFile` attribute is required. This is usually an `.csproj`, or `.sln` file."; @@ -92,11 +93,13 @@ let inherit dotnet-sdk dotnet-test-sdk disabledTests nuget-source dotnet-runtime runtimeDeps buildType; }) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook; - localDeps = if (projectReferences != []) + localDeps = + if (projectReferences != [ ]) then linkFarmFromDrvs "${name}-project-references" projectReferences else null; - _nugetDeps = if lib.isDerivation nugetDeps + _nugetDeps = + if lib.isDerivation nugetDeps then nugetDeps else mkNugetDeps { inherit name; nugetDeps = import nugetDeps; }; @@ -124,8 +127,9 @@ let name = "${name}-nuget-source"; paths = [ _dependenciesSource _sdkSource ]; }; -in stdenvNoCC.mkDerivation (args // { - nativeBuildInputs = args.nativeBuildInputs or [] ++ [ +in +stdenvNoCC.mkDerivation (args // { + nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [ dotnetConfigureHook dotnetBuildHook dotnetCheckHook @@ -150,74 +154,76 @@ in stdenvNoCC.mkDerivation (args // { passthru = { inherit nuget-source; - fetch-deps = let - # Because this list is rather long its put in its own store path to maintain readability of the generated script - exclusions = writeText "nuget-package-exclusions" (lib.concatStringsSep "\n" (dotnet-sdk.passthru.packages { fetchNuGet = attrs: attrs.pname; })); + fetch-deps = + let + # Because this list is rather long its put in its own store path to maintain readability of the generated script + exclusions = writeText "nuget-package-exclusions" (lib.concatStringsSep "\n" (dotnet-sdk.passthru.packages { fetchNuGet = attrs: attrs.pname; })); - runtimeIds = map (system: dotnet-sdk.systemToDotnetRid system) (args.meta.platforms or dotnet-sdk.meta.platforms); + runtimeIds = map (system: dotnet-sdk.systemToDotnetRid system) (args.meta.platforms or dotnet-sdk.meta.platforms); - # Derivations may set flags such as `--runtime ` based on the host platform to avoid restoring/building nuget dependencies they dont have or dont need. - # This introduces an issue; In this script we loop over all platforms from `meta` and add the RID flag for it, as to fetch all required dependencies. - # The script would inherit the RID flag from the derivation based on the platform building the script, and set the flag for any iteration we do over the RIDs. - # That causes conflicts. To circumvent it we remove all occurances of the flag. - flags = - let - hasRid = flag: lib.any (v: v) (map (rid: lib.hasInfix rid flag) (lib.attrValues dotnet-sdk.runtimeIdentifierMap)); - in - builtins.filter (flag: !(hasRid flag)) (dotnetFlags ++ dotnetRestoreFlags); + # Derivations may set flags such as `--runtime ` based on the host platform to avoid restoring/building nuget dependencies they dont have or dont need. + # This introduces an issue; In this script we loop over all platforms from `meta` and add the RID flag for it, as to fetch all required dependencies. + # The script would inherit the RID flag from the derivation based on the platform building the script, and set the flag for any iteration we do over the RIDs. + # That causes conflicts. To circumvent it we remove all occurances of the flag. + flags = + let + hasRid = flag: lib.any (v: v) (map (rid: lib.hasInfix rid flag) (lib.attrValues dotnet-sdk.runtimeIdentifierMap)); + in + builtins.filter (flag: !(hasRid flag)) (dotnetFlags ++ dotnetRestoreFlags); - in writeShellScript "fetch-${pname}-deps" '' - set -euo pipefail + in + writeShellScript "fetch-${pname}-deps" '' + set -euo pipefail - export PATH="${lib.makeBinPath [ coreutils dotnet-sdk nuget-to-nix ]}" + export PATH="${lib.makeBinPath [ coreutils dotnet-sdk nuget-to-nix ]}" - case "''${1-}" in - --help|-h) - echo "usage: $0 [--help]" - echo " The path to write the lockfile to" - echo " --help Show this help message" - exit - ;; - esac + case "''${1-}" in + --help|-h) + echo "usage: $0 [--help]" + echo " The path to write the lockfile to" + echo " --help Show this help message" + exit + ;; + esac - deps_file="$(realpath "''${1:-$(mktemp -t "${pname}-deps-XXXXXX.nix")}")" - export HOME=$(mktemp -td "${pname}-home-XXXXXX") - mkdir -p "$HOME/nuget_pkgs" + deps_file="$(realpath "''${1:-$(mktemp -t "${pname}-deps-XXXXXX.nix")}")" + export HOME=$(mktemp -td "${pname}-home-XXXXXX") + mkdir -p "$HOME/nuget_pkgs" - store_src="${srcOnly args}" - src="$(mktemp -td "${pname}-src-XXXXXX")" - cp -rT "$store_src" "$src" - chmod -R +w "$src" - trap "rm -rf $src $HOME" EXIT + store_src="${srcOnly args}" + src="$(mktemp -td "${pname}-src-XXXXXX")" + cp -rT "$store_src" "$src" + chmod -R +w "$src" + trap "rm -rf $src $HOME" EXIT - cd "$src" - echo "Restoring project..." + cd "$src" + echo "Restoring project..." - export DOTNET_NOLOGO=1 - export DOTNET_CLI_TELEMETRY_OPTOUT=1 + export DOTNET_NOLOGO=1 + export DOTNET_CLI_TELEMETRY_OPTOUT=1 - for rid in "${lib.concatStringsSep "\" \"" runtimeIds}"; do - for project in "${lib.concatStringsSep "\" \"" ((lib.toList projectFile) ++ lib.optionals (testProjectFile != "") (lib.toList testProjectFile))}"; do - dotnet restore "$project" \ - -p:ContinuousIntegrationBuild=true \ - -p:Deterministic=true \ - --packages "$HOME/nuget_pkgs" \ - --runtime "$rid" \ - ${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \ - ${lib.optionalString (flags != []) (toString flags)} - done - done + for rid in "${lib.concatStringsSep "\" \"" runtimeIds}"; do + for project in "${lib.concatStringsSep "\" \"" ((lib.toList projectFile) ++ lib.optionals (testProjectFile != "") (lib.toList testProjectFile))}"; do + dotnet restore "$project" \ + -p:ContinuousIntegrationBuild=true \ + -p:Deterministic=true \ + --packages "$HOME/nuget_pkgs" \ + --runtime "$rid" \ + ${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \ + ${lib.optionalString (flags != []) (toString flags)} + done + done - echo "Succesfully restored project" + echo "Succesfully restored project" - echo "Writing lockfile..." - echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$deps_file" - nuget-to-nix "$HOME/nuget_pkgs" "${exclusions}" >> "$deps_file" - echo "Succesfully wrote lockfile to: $deps_file" - ''; - } // args.passthru or {}; + echo "Writing lockfile..." + echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$deps_file" + nuget-to-nix "$HOME/nuget_pkgs" "${exclusions}" >> "$deps_file" + echo "Succesfully wrote lockfile to: $deps_file" + ''; + } // args.passthru or { }; meta = { platforms = dotnet-sdk.meta.platforms; - } // args.meta or {}; + } // args.meta or { }; })