Skip to content

Commit 2520ce0

Browse files
authored
Merge pull request #13 from input-output-hk/builder-haddock2
builder: Add haddock and hoogle
2 parents 18be956 + 8ad8731 commit 2520ce0

File tree

12 files changed

+275
-18
lines changed

12 files changed

+275
-18
lines changed

builder/comp-builder.nix

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
, preBuild ? null, postBuild ? null
1717
, preCheck ? null, postCheck ? null
1818
, preInstall ? null, postInstall ? null
19+
, preHaddock ? null, postHaddock ? null
1920
, shellHook ? null
2021

2122
, doCheck ? component.doCheck || haskellLib.isTest componentId
@@ -25,6 +26,11 @@
2526

2627
, static ? stdenv.hostPlatform.isMusl
2728
, deadCodeElimination ? true
29+
30+
# Options for Haddock generation
31+
, doHaddock ? component.doHaddock # Enable haddock and hoogle generation
32+
, doHoogle ? true # Also build a hoogle index
33+
, hyperlinkSource ? true # Link documentation to the source code
2834
}:
2935

3036
let
@@ -164,7 +170,8 @@ let
164170
# other flags
165171
"--enable-executable-stripping"
166172
"--enable-library-stripping"
167-
] ++ lib.optional (deadCodeElimination && stdenv.hostPlatform.isLinux) "--enable-split-sections"
173+
] ++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
174+
++ lib.optional (deadCodeElimination && stdenv.hostPlatform.isLinux) "--enable-split-sections"
168175
++ lib.optional (static) "--enable-static"
169176
++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) (
170177
map (arg: "--hsc2hs-option=" + arg) ["--cross-compile" "--via-asm"]
@@ -182,7 +189,14 @@ let
182189
inherit package configFiles;
183190
};
184191

185-
in stdenv.mkDerivation ({
192+
# the target dir for haddock documentation
193+
docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
194+
195+
doHaddock' = doHaddock && (haskellLib.isLibrary componentId);
196+
197+
in stdenv.lib.fix (drv:
198+
199+
stdenv.mkDerivation ({
186200
name = fullName;
187201

188202
inherit src doCheck doCrossCheck dontPatchELF dontStrip;
@@ -192,6 +206,10 @@ in stdenv.mkDerivation ({
192206
config = component;
193207
inherit configFiles;
194208
env = shellWrappers;
209+
210+
# The directory containing the haddock documentation.
211+
# `null' if no haddock documentation was built.
212+
haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
195213
};
196214

197215
meta = {
@@ -216,13 +234,17 @@ in stdenv.mkDerivation ({
216234
++ component.pkgconfig;
217235

218236
nativeBuildInputs =
219-
[ghc]
237+
[ghc buildPackages.removeReferencesTo]
220238
++ lib.optional (component.pkgconfig != []) pkgconfig
221239
++ executableToolDepends;
222240

223241
SETUP_HS = setup + /bin/Setup;
224242

243+
outputs = ["out" ] ++ (lib.optional doHaddock' "doc");
244+
225245
# Phases
246+
preInstallPhases = lib.optional doHaddock' "haddockPhase";
247+
226248
prePatch = lib.optionalString (cabalFile != null) ''
227249
cat ${cabalFile} > ${package.identifier.name}.cabal
228250
'';
@@ -250,6 +272,32 @@ in stdenv.mkDerivation ({
250272
runHook postCheck
251273
'';
252274

275+
haddockPhase = ''
276+
runHook preHaddock
277+
docdir="${docdir "$doc"}"
278+
mkdir -p "$docdir"
279+
280+
$SETUP_HS haddock \
281+
"--html" \
282+
${lib.optionalString doHoogle "--hoogle"} \
283+
${lib.optionalString hyperlinkSource "--hyperlink-source"} \
284+
${lib.concatStringsSep " " component.setupHaddockFlags}
285+
286+
html="dist/doc/html/${componentId.cname}"
287+
288+
if [ -d "$html" ]; then
289+
# Ensure that libraries are not pulled into the docs closure.
290+
# As an example, the prettified source code of a
291+
# Paths_package module will contain store paths of the library package.
292+
for x in "$html/src/"*.html; do
293+
remove-references-to -t $out $x
294+
done
295+
296+
cp -R "$html" "$docdir"/html
297+
fi
298+
runHook postHaddock
299+
'';
300+
253301
# Note: Cabal does *not* copy test executables during the `install` phase.
254302
installPhase = ''
255303
runHook preInstall
@@ -278,15 +326,10 @@ in stdenv.mkDerivation ({
278326
}
279327
# patches can (if they like) depend on the version and revision of the package.
280328
// lib.optionalAttrs (patches != []) { patches = map (p: if builtins.isFunction p then p { inherit (package.identifier) version; inherit revision; } else p) patches; }
281-
// lib.optionalAttrs (preUnpack != "") { inherit preUnpack; }
282-
// lib.optionalAttrs (postUnpack != "") { inherit postUnpack; }
283-
// lib.optionalAttrs (preConfigure != "") { inherit preConfigure; }
284-
// lib.optionalAttrs (postConfigure != "") { inherit postConfigure; }
285-
// lib.optionalAttrs (preBuild != "") { inherit preBuild; }
286-
// lib.optionalAttrs (postBuild != "") { inherit postBuild; }
287-
// lib.optionalAttrs (preCheck != "") { inherit preCheck; }
288-
// lib.optionalAttrs (postCheck != "") { inherit postCheck; }
289-
// lib.optionalAttrs (preInstall != "") { inherit preInstall; }
290-
// lib.optionalAttrs (postInstall != "") { inherit postInstall; }
329+
// haskellLib.optionalHooks {
330+
inherit preUnpack postUnpack preConfigure postConfigure
331+
preBuild postBuild preCheck postCheck
332+
preInstall postInstall preHaddock postHaddock;
333+
}
291334
// lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive"; }
292-
)
335+
))

builder/default.nix

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
, postCheck
2222
, preInstall
2323
, postInstall
24+
, preHaddock
25+
, postHaddock
2426

2527
, shellHook
2628

@@ -73,7 +75,9 @@ let
7375

7476
buildComp = componentId: component: comp-builder {
7577
inherit componentId component package name src flags setup cabalFile patches revision
76-
preUnpack postUnpack preConfigure postConfigure preBuild postBuild preCheck postCheck preInstall postInstall
78+
preUnpack postUnpack preConfigure postConfigure
79+
preBuild postBuild preCheck postCheck
80+
preInstall postInstall preHaddock postHaddock
7781
shellHook
7882
;
7983
};

lib/default.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ with haskellLib;
6161
if componentId.ctype == "all" then ""
6262
else "${componentId.ctype}:${componentId.cname}";
6363

64+
# Remove null or empty values from an attrset.
65+
optionalHooks = lib.filterAttrs (_: hook: hook != null && hook != "");
66+
6467
# Avoid pkgs.callPackage for now. It does a lot of nonsense with OOP
6568
# style programming that we should avoid until we know we want it.
6669

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,11 @@ in {
147151
type = bool;
148152
default = config.doCrossCheck;
149153
};
154+
doHaddock = mkOption {
155+
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
156+
type = bool;
157+
default = config.doHaddock;
158+
};
150159
};
151160
};
152161
in {
@@ -225,6 +234,10 @@ in {
225234
type = listOfFilteringNulls str;
226235
default = [];
227236
};
237+
setupHaddockFlags = mkOption {
238+
type = listOfFilteringNulls str;
239+
default = [];
240+
};
228241
preUnpack = mkOption {
229242
type = nullOr lines;
230243
default = null;
@@ -265,6 +278,14 @@ in {
265278
type = nullOr string;
266279
default = null;
267280
};
281+
preHaddock = mkOption {
282+
type = nullOr string;
283+
default = null;
284+
};
285+
postHaddock = mkOption {
286+
type = nullOr string;
287+
default = null;
288+
};
268289
shellHook = mkOption {
269290
type = nullOr string;
270291
default = null;
@@ -282,6 +303,11 @@ in {
282303
type = bool;
283304
default = false;
284305
};
306+
doHaddock = mkOption {
307+
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
# Add a hook to the haddock phase
27+
packages.test-haddock.postHaddock = ''
28+
echo "==="
29+
echo "This is the postHaddock hook. The files are:"
30+
find .
31+
echo "==="
32+
'';
33+
34+
# Check that the package option works
35+
packages.stm.doHaddock = false;
36+
}
37+
];
38+
};
39+
40+
packages = pkgSet.config.hsPkgs;
41+
42+
in
43+
stdenv.mkDerivation {
44+
name = "builder-haddock-test";
45+
46+
buildCommand = let
47+
inherit (packages.test-haddock.components) library;
48+
noDocLibrary = packages.stm.components.library;
49+
in ''
50+
########################################################################
51+
# test haddock
52+
53+
doc="${toString library.doc}"
54+
docDir="${toString library.haddockDir}"
55+
56+
# exeDoc="$ disabled {toString packages.test-haddock.components.exes.test-haddock.doc}"
57+
# printf "checking that executable output does not have docs ... " >& 2
58+
# echo $exeDoc
59+
# test "$exeDoc" = ""
60+
61+
printf "checking that documentation directory was built... " >& 2
62+
echo "$doc" >& 2
63+
test -n "$doc"
64+
65+
printf "checking that documentation was generated... " >& 2
66+
grep hello "$docDir/TestHaddock.html" > /dev/null
67+
echo yes >& 2
68+
69+
printf "checking for hoogle index of package... " >& 2
70+
grep hello "$docDir/test-haddock.txt" > /dev/null
71+
echo yes >& 2
72+
73+
printf "checking for absence of documentation in another package... " >& 2
74+
if [ -d "${toString noDocLibrary.haddockDir}" ]; then
75+
echo "it exists - FAIL" >& 2
76+
else
77+
echo PASS >& 2
78+
fi
79+
80+
printf "checking for absence of library package store paths in docs... " >& 2
81+
if grep -R ${library} "$docDir" > /dev/null; then
82+
echo "Found ${library} - FAIL" >& 2
83+
exit 1
84+
else
85+
echo "PASS" >& 2
86+
fi
87+
88+
touch $out
89+
'';
90+
91+
meta.platforms = platforms.all;
92+
} // { inherit packages pkgSet; }

test/builder-haddock/plan.nix

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
hackage:
2+
{
3+
packages = {
4+
"ghc-prim".revision = hackage."ghc-prim"."0.5.2.0".revisions.default;
5+
"stm".revision = hackage."stm"."2.4.5.1".revisions.default;
6+
"rts".revision = hackage."rts"."1.0".revisions.default;
7+
"base".revision = hackage."base"."4.11.1.0".revisions.default;
8+
"array".revision = hackage."array"."0.5.2.0".revisions.default;
9+
"integer-gmp".revision = hackage."integer-gmp"."1.0.2.0".revisions.default;
10+
};
11+
compiler = {
12+
version = "8.4.4";
13+
nix-name = "ghc844";
14+
packages = {
15+
"ghc-prim" = "0.5.2.0";
16+
"stm" = "2.4.5.1";
17+
"rts" = "1.0";
18+
"base" = "4.11.1.0";
19+
"array" = "0.5.2.0";
20+
"integer-gmp" = "1.0.2.0";
21+
};
22+
};
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
cabal-version: 2.2
2+
name: test-haddock
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_haddock
11+
-- other-extensions:
12+
build-depends: base ^>=4.11.1.0
13+
, stm
14+
-- hs-source-dirs:
15+
default-language: Haskell2010

0 commit comments

Comments
 (0)