Search code examples
haskellcabal-installnix

Is it possible to keep the test suite logs generated by Cabal when run through nix-build?


I have a .cabal file specifying a test suite, and a default.nix file generated with cabal2nix.

Then I have a release.nix file (containing something like pkgs.haskell.packages.ghc802.callPackage ./default.nix {}) that I can nix-build.

It works: I have a result symlink with my program.

While compiling my program with nix-build, I see in the output this line: Test suite logged to: dist/test/myprogram-0.0.0-test-suite.log (I guess produced indirectly by cabal test), but the file seems to be discarded.

Is it possible to keep around that log file (possibly within the directory pointed to by the result symlink) ?


Solution

  • Keeping the log files in case the test suite was successful

    You can specify a shell script which gets executed after the test suite is run by postCheck. This is only executed, if the test suite is successful.

    Calling cabal2nix with or without --shell will contain a derivation like that in the output:

     { mkDerivation, base, stdenv }:
          mkDerivation {
            pname = "sample";
            version = "0.0.0.1";
            src = ./.;
            isLibrary = false;
            isExecutable = true;
            executableHaskellDepends = [ base ];
            testHaskellDepends = [ base ];
            license = stdenv.lib.licenses.unfree;
            hydraPlatforms = stdenv.lib.platforms.none;
          };
    

    All you have to add is

     postCheck = ''
                  mkdir -p $out/logs
                  find dist/test -name \*log -exec cp '{}' $out/logs \;
                '';
    

    and you will find your log files in result/logs.

    The whole derivation will now look like:

     { mkDerivation, base, stdenv }:
          mkDerivation {
            pname = "sample";
            version = "0.0.0.1";
            src = ./.;
            isLibrary = false;
            isExecutable = true;
            executableHaskellDepends = [ base ];
            testHaskellDepends = [ base ];
            license = stdenv.lib.licenses.unfree;
            hydraPlatforms = stdenv.lib.platforms.none;
            postCheck = ''
                  mkdir -p $out/logs
                  find dist/test -name \*log -exec cp '{}' $out/logs \;
                '';
          };
    

    Keeping the log files in case the test suite failed

    If you want to look at these log files in case the test suite fails, you can call nix-build with the option --keep-failed or -K. This way it will keep the temporary build directory and print a message like

    note: keeping build directory '/tmp/nix-build-sample-0.0.0.1.drv-0'
    

    near the end of its output (third to last line for me). You will find the log files in that directory. In my example, they have been placed in

    /tmp/nix-build-sample-0.0.0.1.drv-0/sample/dist/test