Skip to content

Commit 3f8c7e9

Browse files
committed
builder: Add haddock and hoogle to components.library.doc
1 parent 70f01c2 commit 3f8c7e9

File tree

9 files changed

+216
-1
lines changed

9 files changed

+216
-1
lines changed

builder/comp-builder.nix

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
, doCrossCheck ? component.doCrossCheck || false
2323
, dontPatchELF ? true
2424
, dontStrip ? true
25+
, doHaddock ? true
26+
, doHoogle ? true
27+
, hyperlinkSource ? true
2528

2629
, static ? stdenv.hostPlatform.isMusl
2730
, deadCodeElimination ? true
@@ -157,6 +160,8 @@ let
157160
"--with-ld=${stdenv.cc.bintools.targetPrefix}ld"
158161
"--with-ar=${stdenv.cc.bintools.targetPrefix}ar"
159162
"--with-strip=${stdenv.cc.bintools.targetPrefix}strip"
163+
# HADDOCK
164+
"--docdir=${docdir "$doc"}"
160165
# other flags
161166
"--enable-executable-stripping"
162167
"--enable-library-stripping"
@@ -178,6 +183,9 @@ let
178183
inherit package configFiles;
179184
};
180185

186+
# the target dir for haddock documentation
187+
docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
188+
181189
in stdenv.mkDerivation ({
182190
name = fullName;
183191

@@ -188,6 +196,12 @@ in stdenv.mkDerivation ({
188196
config = component;
189197
inherit configFiles;
190198
env = shellWrappers;
199+
200+
# Given the haskell package, returns
201+
# the directory containing the haddock documentation.
202+
# `null' if no haddock documentation was built.
203+
# TODO: fetch the self from the fixpoint instead
204+
haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null;
191205
};
192206

193207
meta = {
@@ -212,13 +226,17 @@ in stdenv.mkDerivation ({
212226
++ component.pkgconfig;
213227

214228
nativeBuildInputs =
215-
[ghc]
229+
[ghc buildPackages.removeReferencesTo]
216230
++ lib.optional (component.pkgconfig != []) pkgconfig
217231
++ executableToolDepends;
218232

219233
SETUP_HS = setup + /bin/Setup;
220234

235+
outputs = ["out" ] ++ (lib.optional (haskellLib.isLibrary componentId) "doc");
236+
221237
# Phases
238+
preInstallPhases = ["haddockPhase"];
239+
222240
prePatch = lib.optionalString (cabalFile != null) ''
223241
cat ${cabalFile} > ${package.identifier.name}.cabal
224242
'';
@@ -246,6 +264,35 @@ in stdenv.mkDerivation ({
246264
runHook postCheck
247265
'';
248266

267+
haddockPhase = ''
268+
runHook preHaddock
269+
${lib.optionalString (doHaddock && (haskellLib.isLibrary componentId)) ''
270+
docdir="${docdir "$doc"}"
271+
mkdir -p "$docdir"
272+
273+
$SETUP_HS haddock \
274+
"--html" \
275+
${lib.optionalString doHoogle "--hoogle"} \
276+
${lib.optionalString hyperlinkSource "--hyperlink-source"} \
277+
${lib.concatStringsSep " " component.setupHaddockFlags} \
278+
|| true # some packages don't have haddock documentation
279+
280+
html="dist/doc/html/${componentId.cname}"
281+
282+
if [ -d "$html" ]; then
283+
# Ensure that libraries are not pulled into the docs closure.
284+
# As an example, the prettified source code of a
285+
# Paths_package module will contain store paths of the library package.
286+
for x in "$html/src/"*.html; do
287+
remove-references-to -t $out $x
288+
done
289+
290+
cp -R "$html" "$docdir"/html
291+
fi
292+
''}
293+
runHook postHaddock
294+
'';
295+
249296
# Note: Cabal does *not* copy test executables during the `install` phase.
250297
installPhase = ''
251298
runHook preInstall

modules/package.nix

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ in {
135135
type = listOfFilteringNulls str;
136136
default = config.setupInstallFlags;
137137
};
138+
setupHaddockFlags = mkOption {
139+
type = listOfFilteringNulls str;
140+
default = config.setupHaddockFlags;
141+
};
138142
doExactConfig = mkOption {
139143
type = bool;
140144
default = config.doExactConfig;
@@ -147,6 +151,14 @@ in {
147151
type = bool;
148152
default = config.doCrossCheck;
149153
};
154+
doHaddock = mkOption {
155+
type = bool;
156+
default = config.doHaddock;
157+
};
158+
doHoogle = mkOption {
159+
type = bool;
160+
default = config.doHoogle;
161+
};
150162
};
151163
};
152164
in {
@@ -225,6 +237,10 @@ in {
225237
type = listOfFilteringNulls str;
226238
default = [];
227239
};
240+
setupHaddockFlags = mkOption {
241+
type = listOfFilteringNulls str;
242+
default = [];
243+
};
228244
preUnpack = mkOption {
229245
type = nullOr lines;
230246
default = null;
@@ -282,6 +298,16 @@ in {
282298
type = bool;
283299
default = false;
284300
};
301+
doHaddock = mkOption {
302+
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
303+
type = bool;
304+
default = true;
305+
};
306+
doHoogle = mkOption {
307+
description = "Enable generation of a Hoogle index while building the Haddock documentation.";
308+
type = bool;
309+
default = true;
310+
};
285311
};
286312

287313
# This has one quirk. Manually setting options on the all component

test/builder-haddock/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

test/builder-haddock/TestHaddock.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- | Haddock test stuff
2+
module TestHaddock (hello) where
3+
4+
-- | Standard hello text.
5+
hello :: String
6+
hello = "Hello, world!"

test/builder-haddock/default.nix

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{ pkgs
2+
, haskell
3+
, stdenv
4+
}:
5+
6+
with stdenv.lib;
7+
8+
let
9+
pkgSet = haskell.mkPkgSet {
10+
inherit pkgs;
11+
# generated with:
12+
# cabal new-build
13+
# plan-to-nix dist-newstyle/cache/plan.json > plan.nix
14+
# cabal-to-nix test-haddock.cabal > test-haddock.nix
15+
pkg-def = import ./plan.nix;
16+
pkg-def-overlays = [
17+
{ test-haddock = ./test-haddock.nix; }
18+
];
19+
modules = [
20+
# overrides to fix the build
21+
{
22+
packages.transformers-compat.components.library.doExactConfig = true;
23+
}
24+
];
25+
};
26+
27+
packages = pkgSet.config.hsPkgs;
28+
29+
in
30+
stdenv.mkDerivation {
31+
name = "with-packages-test";
32+
33+
buildCommand = let
34+
inherit (packages.test-haddock.components) library;
35+
in ''
36+
########################################################################
37+
# test haddock
38+
39+
doc="${toString library.doc}"
40+
docDir="${toString (library.haddockDir library)}"
41+
42+
# exeDoc="$ disabled {toString packages.test-haddock.components.exes.test-haddock.doc}"
43+
# printf "checking that executable output does not have docs ... " >& 2
44+
# echo $exeDoc
45+
# test "$exeDoc" = ""
46+
47+
printf "checking that documentation directory was built... " >& 2
48+
echo "$doc" >& 2
49+
test -n "$doc"
50+
51+
printf "checking that documentation was generated... " >& 2
52+
grep hello "$docDir/TestHaddock.html" > /dev/null
53+
echo yes >& 2
54+
55+
printf "checking for absence of library package store paths in docs... " >& 2
56+
if grep -R ${library} "$docDir" > /dev/null; then
57+
echo "Found ${library} - FAIL" >& 2
58+
exit 1
59+
else
60+
echo "PASS" >& 2
61+
fi
62+
63+
touch $out
64+
'';
65+
66+
meta.platforms = platforms.all;
67+
} // { inherit packages pkgSet; }

test/builder-haddock/plan.nix

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
hackage:
2+
{
3+
packages = {
4+
"ghc-prim".revision = hackage."ghc-prim"."0.5.2.0".revisions.default;
5+
"rts".revision = hackage."rts"."1.0".revisions.default;
6+
"base".revision = hackage."base"."4.11.1.0".revisions.default;
7+
"integer-gmp".revision = hackage."integer-gmp"."1.0.2.0".revisions.default;
8+
};
9+
compiler = {
10+
version = "8.4.4";
11+
nix-name = "ghc844";
12+
packages = {
13+
"ghc-prim" = "0.5.2.0";
14+
"rts" = "1.0";
15+
"base" = "4.11.1.0";
16+
"integer-gmp" = "1.0.2.0";
17+
};
18+
};
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
cabal-version: 2.2
2+
name: test-with-packages
3+
version: 0.1.0.0
4+
license: NONE
5+
author: Rodney Lorrimar
6+
maintainer: [email protected]
7+
8+
library
9+
exposed-modules: TestHaddock
10+
other-modules: Paths_test_with_packages
11+
-- other-extensions:
12+
build-depends: base ^>=4.11.1.0
13+
-- hs-source-dirs:
14+
default-language: Haskell2010

test/builder-haddock/test-haddock.nix

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{ system
2+
, compiler
3+
, flags
4+
, pkgs
5+
, hsPkgs
6+
, pkgconfPkgs
7+
, ... }:
8+
{
9+
flags = {};
10+
package = {
11+
specVersion = "2.2";
12+
identifier = {
13+
name = "test-with-packages";
14+
version = "0.1.0.0";
15+
};
16+
license = "NONE";
17+
copyright = "";
18+
maintainer = "[email protected]";
19+
author = "Rodney Lorrimar";
20+
homepage = "";
21+
url = "";
22+
synopsis = "";
23+
description = "";
24+
buildType = "Simple";
25+
};
26+
components = {
27+
"library" = {
28+
depends = [ (hsPkgs.base) ];
29+
};
30+
};
31+
} // rec {
32+
src = pkgs.lib.mkDefault ./.;
33+
}

test/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ in {
1919
cabal-simple = callPackage ./cabal-simple { inherit haskell; };
2020
cabal-22 = callPackage ./cabal-22 { inherit haskell; };
2121
with-packages = callPackage ./with-packages { inherit haskell; };
22+
builder-haddock = callPackage ./builder-haddock { inherit haskell; };
2223

2324
# Run unit tests with: nix-instantiate --eval --strict -A unit
2425
# An empty list means success.

0 commit comments

Comments
 (0)