at master 4.3 kB view raw
1# Install not only the Hoogle library and executable, but also a local Hoogle 2# database which provides "Source" links to all specified 'packages' -- or the 3# current Haskell Platform if no custom package set is provided. 4 5{ 6 lib, 7 stdenv, 8 buildPackages, 9 haskellPackages, 10 writeText, 11 runCommand, 12}: 13 14# This argument is a function which selects a list of Haskell packages from any 15# passed Haskell package set. 16# 17# Example: 18# (hpkgs: [ hpkgs.mtl hpkgs.lens ]) 19selectPackages: 20 21let 22 inherit (haskellPackages) ghc hoogle; 23 packages = selectPackages haskellPackages; 24 25 wrapper = ./hoogle-local-wrapper.sh; 26 haddockExe = "haddock"; 27 ghcDocLibDir = ghc.doc + "/share/doc/ghc*/html/libraries"; 28 prologue = "${ghcDocLibDir}/prologue.txt"; 29 30 docPackages = 31 lib.closePropagation 32 # we grab the doc outputs 33 (map (lib.getOutput "doc") packages); 34 35 # Hoogle database path, relative to `$out`. 36 databasePath = "share/doc/hoogle/default.hoo"; 37 38in 39buildPackages.stdenv.mkDerivation (finalAttrs: { 40 name = "hoogle-with-packages"; 41 buildInputs = [ 42 ghc 43 hoogle 44 ]; 45 46 # compiling databases takes less time than copying the results 47 # between machines. 48 preferLocalBuild = true; 49 50 # we still allow substitutes because a database is relatively small and if it 51 # is already built downloading is probably faster. The substitution will only 52 # trigger for users who have already cached the database on a substituter and 53 # thus probably intend to substitute it. 54 allowSubstitutes = true; 55 56 inherit docPackages; 57 58 passAsFile = [ "buildCommand" ]; 59 60 buildCommand = '' 61 ${ 62 let 63 # Filter out nulls here to work around https://github.com/NixOS/nixpkgs/issues/82245 64 # If we don't then grabbing `p.name` here will fail. 65 packages' = lib.filter (p: p != null) packages; 66 in 67 lib.optionalString (packages' != [ ] -> docPackages == [ ]) ( 68 "echo WARNING: localHoogle package list empty, even though" 69 + " the following were specified: " 70 + lib.concatMapStringsSep ", " (p: p.name) packages' 71 ) 72 } 73 mkdir -p $out/share/doc/hoogle 74 75 echo importing builtin packages 76 for docdir in ${ghcDocLibDir}"/"*; do 77 name="$(basename $docdir)" 78 if [[ -d $docdir ]]; then 79 ln -sfn $docdir $out/share/doc/hoogle/$name 80 fi 81 done 82 83 echo importing other packages 84 ${lib.concatMapStringsSep "\n" 85 (el: '' 86 ln -sfn ${el.haddockDir} "$out/share/doc/hoogle/${el.name}" 87 '') 88 ( 89 lib.filter (el: el.haddockDir != null) ( 90 builtins.map (p: { 91 haddockDir = if p ? haddockDir then p.haddockDir p else null; 92 name = p.pname; 93 }) docPackages 94 ) 95 ) 96 } 97 98 databasePath="$out/"${lib.escapeShellArg databasePath} 99 100 echo building hoogle database 101 hoogle generate --database "$databasePath" --local=$out/share/doc/hoogle 102 103 echo building haddock index 104 # adapted from GHC's gen_contents_index 105 cd $out/share/doc/hoogle 106 107 args= 108 for hdfile in $(ls -1 *"/"*.haddock | grep -v '/ghc\.haddock' | sort); do 109 name_version=`echo "$hdfile" | sed 's#/.*##'` 110 args="$args --read-interface=$name_version,$hdfile" 111 done 112 113 ${ghc}/bin/${haddockExe} --gen-index --gen-contents -o . \ 114 -t "Haskell Hierarchical Libraries" \ 115 -p ${prologue} \ 116 $args 117 118 echo finishing up 119 mkdir -p $out/bin 120 substitute ${wrapper} $out/bin/hoogle \ 121 --subst-var-by shell ${stdenv.shell} \ 122 --subst-var-by database "$databasePath" \ 123 --subst-var-by hoogle ${hoogle} 124 chmod +x $out/bin/hoogle 125 ''; 126 127 passthru = { 128 isHaskellLibrary = false; # for the filter in ./with-packages-wrapper.nix 129 130 # The path to the Hoogle database. 131 database = "${finalAttrs.finalPackage}/${databasePath}"; 132 133 tests.can-search-database = runCommand "can-search-database" { } '' 134 # This succeeds even if no results are found, but `Prelude.map` should 135 # always be available. 136 ${finalAttrs.finalPackage}/bin/hoogle search Prelude.map > $out 137 ''; 138 }; 139 140 meta = { 141 description = "Local Hoogle database"; 142 platforms = ghc.meta.platforms; 143 hydraPlatforms = with lib.platforms; none; 144 maintainers = with lib.maintainers; [ ttuegel ]; 145 }; 146})