Merge pull request #28744 from LumiGuide/checkUnusedPackages

haskell: add the checkUnusedPackages function including docs
This commit is contained in:
Peter Simons 2017-08-30 15:05:21 +02:00 committed by GitHub
commit 8a0566e4c8
2 changed files with 73 additions and 1 deletions

View File

@ -867,6 +867,62 @@ use the following to get the `scientific` package build with `integer-simple`:
nix-build -A haskell.packages.integer-simple.ghc802.scientific nix-build -A haskell.packages.integer-simple.ghc802.scientific
``` ```
### Quality assurance
The `haskell.lib` library includes a number of functions for checking for
various imperfections in Haskell packages. It's useful to apply these functions
to your own Haskell packages and integrate that in a Continuous Integration
server like [hydra](https://nixos.org/hydra/) to assure your packages maintain a
minimum level of quality. This section discusses some of these functions.
#### buildStrictly
Applying `haskell.lib.buildStrictly` to a Haskell package enables the `-Wall`
and `-Werror` GHC options to turn all warnings into build failures. Additionally
the source of your package is gotten from first invoking `cabal sdist` to ensure
all needed files are listed in the Cabal file.
#### checkUnusedPackages
Applying `haskell.lib.checkUnusedPackages` to a Haskell package invokes
the [packunused](http://hackage.haskell.org/package/packunused) tool on the
package. `packunused` complains when it finds packages listed as build-depends
in the Cabal file which are redundant. For example:
```
$ nix-build -E 'let pkgs = import <nixpkgs> {}; in pkgs.haskell.lib.checkUnusedPackages {} pkgs.haskellPackages.scientific'
these derivations will be built:
/nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv
...
detected package components
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- library
- testsuite(s): test-scientific
- benchmark(s): bench-scientific*
(component names suffixed with '*' are not configured to be built)
library
~~~~~~~
The following package dependencies seem redundant:
- ghc-prim-0.5.0.0
testsuite(test-scientific)
~~~~~~~~~~~~~~~~~~~~~~~~~~
no redundant packages dependencies found
builder for /nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv failed with exit code 1
error: build of /nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv failed
```
As you can see, `packunused` finds out that although the testsuite component has
no redundant dependencies the library component of `scientific-0.3.5.1` depends
on `ghc-prim` which is unused in the library.
## Other resources ## Other resources
- The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE) - The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE)

View File

@ -1,5 +1,5 @@
# TODO(@Ericson2314): Remove `pkgs` param, which is only used for # TODO(@Ericson2314): Remove `pkgs` param, which is only used for
# `buildStackProject` and `justStaticExecutables` # `buildStackProject`, `justStaticExecutables` and `checkUnusedPackages`
{ pkgs, lib }: { pkgs, lib }:
rec { rec {
@ -108,6 +108,22 @@ rec {
buildStrictly = pkg: buildFromSdist (appendConfigureFlag pkg "--ghc-option=-Wall --ghc-option=-Werror"); buildStrictly = pkg: buildFromSdist (appendConfigureFlag pkg "--ghc-option=-Wall --ghc-option=-Werror");
checkUnusedPackages =
{ ignoreEmptyImports ? false
, ignoreMainModule ? false
, ignorePackages ? []
} : drv :
overrideCabal (appendConfigureFlag drv "--ghc-option=-ddump-minimal-imports") (_drv: {
postBuild = with lib;
let args = concatStringsSep " " (
optional ignoreEmptyImports "--ignore-empty-imports" ++
optional ignoreMainModule "--ignore-main-module" ++
map (pkg: "--ignore-package ${pkg}") ignorePackages
);
in "${pkgs.haskellPackages.packunused}/bin/packunused" +
optionalString (args != "") " ${args}";
});
buildStackProject = pkgs.callPackage ./generic-stack-builder.nix { }; buildStackProject = pkgs.callPackage ./generic-stack-builder.nix { };
triggerRebuild = drv: i: overrideCabal drv (drv: { postUnpack = ": trigger rebuild ${toString i}"; }); triggerRebuild = drv: i: overrideCabal drv (drv: { postUnpack = ": trigger rebuild ${toString i}"; });