diff --git a/pkgs/development/haskell-modules/generic-builder.nix b/pkgs/development/haskell-modules/generic-builder.nix index 94cc50b830769..97d319b200959 100644 --- a/pkgs/development/haskell-modules/generic-builder.nix +++ b/pkgs/development/haskell-modules/generic-builder.nix @@ -209,6 +209,10 @@ in enableSeparateDataOutput ? false, enableSeparateDocOutput ? doHaddock, enableSeparateIntermediatesOutput ? false, + # When enabled test suites are not run in the main deriviation. + # Instead they are built, installed in the 'tests' output, and + # a passthru.test derivation is created for test suites. + enableSeparateTestOutput ? false, # Don't fail at configure time if there are multiple versions of the # same package in the (recursive) dependencies of the package being # built. Will delay failures, if any, to compile time. @@ -636,7 +640,8 @@ lib.fix ( ++ (optional enableSeparateDataOutput "data") ++ (optional enableSeparateDocOutput "doc") ++ (optional enableSeparateBinOutput "bin") - ++ (optional enableSeparateIntermediatesOutput "intermediates"); + ++ (optional enableSeparateIntermediatesOutput "intermediates") + ++ (optional enableSeparateTestOutput "tests"); setOutputFlags = false; @@ -845,7 +850,7 @@ lib.fix ( # - If it is empty, it'll be unset during test suite execution. # - Otherwise GHC_PACKAGE_PATH will have the package db used for configuring # plus GHC's core packages. - checkPhase = '' + ${if enableSeparateTestOutput then "checkPhase" else null} = '' runHook preCheck checkFlagsArray+=( "--show-details=streaming" @@ -922,6 +927,25 @@ lib.fix ( mkdir -p $doc ''} ${optionalString enableSeparateDataOutput "mkdir -p $data"} + ${optionalString enableSeparateTestOutput ( + # if no testTargets are specified but this flag is enabled, then we should query Cabal for the list of all test suites and install them + if testTargets == [ ] then + '' + mkdir -p $test/bin + tests="$(${setupCommand} test ${buildFlags} -v0 --test-wrapper echo)" + for t in $tests; do + install $t $test/bin/ + done + '' + # otherwise just install the test suites specified by testTargets + else + '' + mkdir -p $test/bin + for t in ${testTargetsString}; do + install dist/build/$t/$t $test/bin/ + done + '' + )} runHook postInstall ''; @@ -990,6 +1014,41 @@ lib.fix ( benchmarkToolDepends ; }; + tests = + passthru.tests or { } + // lib.optionalAttrs enableSeparateTestOutput { + checks = ( + stdenv.mkDerivation { + name = "${pname}-check"; + inherit + src + preCheck + postCheck + patches + ; + inherit (drv) meta LANG buildInputs; + phases = [ + "unpackPhase" + "patchPhase" + "checkPhase" + "installPhase" + ]; + checkPhase = '' + runHook preCheck + for t in ${drv.test}/bin/*; do + $t $checkFlags ${lib.concatStringsSep " " testFlags} 2> >(tee $(basename $t)-stderr) | tee $(basename $t)-stdout + done + runHook postCheck + ''; + installPhase = '' + mkdir $out + cp *-stderr $out/ + cp *-stdout $out/ + ''; + } + // lib.optionalAttrs (drv ? LOCALE_ARCHIVE) { inherit (drv) LOCALE_ARCHIVE; } + ); + }; # Attributes for the old definition of `shellFor`. Should be removed but # this predates the warning at the top of `getCabalDeps`. diff --git a/pkgs/development/haskell-modules/lib/compose.nix b/pkgs/development/haskell-modules/lib/compose.nix index 055e6c40c784d..516e4444c0e71 100644 --- a/pkgs/development/haskell-modules/lib/compose.nix +++ b/pkgs/development/haskell-modules/lib/compose.nix @@ -337,6 +337,10 @@ rec { enableSeparateBinOutput = true; }); + enableSeparateTestOutput = overrideCabal (drv: { + enableSeparateTestOutput = true; + }); + appendPatch = x: appendPatches [ x ]; appendPatches = xs: diff --git a/pkgs/development/haskell-modules/lib/default.nix b/pkgs/development/haskell-modules/lib/default.nix index 665d8429631df..8948cb1cb7cee 100644 --- a/pkgs/development/haskell-modules/lib/default.nix +++ b/pkgs/development/haskell-modules/lib/default.nix @@ -214,6 +214,7 @@ rec { disableStaticLibraries = compose.disableStaticLibraries; enableSeparateBinOutput = compose.enableSeparateBinOutput; + enableSeparateTestOutput = compose.enableSeparateTestOutput; appendPatch = drv: x: compose.appendPatch x drv; appendPatches = drv: xs: compose.appendPatches xs drv;