From 8c3f749eda2fb7e8470ce7779c9de20fe415f266 Mon Sep 17 00:00:00 2001
From: Thomas Tuegel <ttuegel@gmail.com>
Date: Mon, 8 Sep 2014 06:26:29 -0500
Subject: [PATCH] Rewrite hoogleLocal expression

The old expression was broken. This began as an attempt to fix it, but
the new expression is substantially different. It takes advantage of new
features that obviate the need to patch Hoogle. It comes with several
limitations. The new expression does not build the database in parallel,
although it does not take long. The new expression also does not support
downloading databases from the Hoogle instance at haskell.org; those
databases link to Hackage for documentation, defying the meaning of local.
---
 .../haskell/hoogle/hoogle-local-wrapper.sh    |   6 +
 .../haskell/hoogle/hoogle-local.diff          |  28 -----
 .../libraries/haskell/hoogle/local.nix        | 106 ++++++++----------
 pkgs/top-level/haskell-packages.nix           |   4 +-
 4 files changed, 52 insertions(+), 92 deletions(-)
 create mode 100644 pkgs/development/libraries/haskell/hoogle/hoogle-local-wrapper.sh
 delete mode 100644 pkgs/development/libraries/haskell/hoogle/hoogle-local.diff

diff --git a/pkgs/development/libraries/haskell/hoogle/hoogle-local-wrapper.sh b/pkgs/development/libraries/haskell/hoogle/hoogle-local-wrapper.sh
new file mode 100644
index 000000000000..c7b15b8f99de
--- /dev/null
+++ b/pkgs/development/libraries/haskell/hoogle/hoogle-local-wrapper.sh
@@ -0,0 +1,6 @@
+#! @shell@
+
+COMMAND=$1
+shift
+HOOGLE_DOC_PATH=@out@/share/hoogle/doc exec @hoogle@/bin/hoogle \
+    $COMMAND -d @out@/share/hoogle $@
diff --git a/pkgs/development/libraries/haskell/hoogle/hoogle-local.diff b/pkgs/development/libraries/haskell/hoogle/hoogle-local.diff
deleted file mode 100644
index df507c5a4705..000000000000
--- a/pkgs/development/libraries/haskell/hoogle/hoogle-local.diff
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/src/CmdLine/All.hs b/src/CmdLine/All.hs
-index 94b1d48..f41f270 100644
---- a/src/CmdLine/All.hs
-+++ b/src/CmdLine/All.hs
-@@ -86,8 +86,10 @@ guessLocal = do
-     ghc <- findExecutable "ghc"
-     home <- getHomeDirectory
-     lib <- getLibDir
-+    path <- lookup "HOOGLE_DOC_PATH" <$> getEnvironment
-     let xs = [takeDirectory (takeDirectory lib) </> "doc" {- Windows, installed with Cabal -}  ] ++
-              [takeDirectory (takeDirectory ghc) </> "doc/html/libraries" | Just ghc <- [ghc] {- Windows, installed by GHC -} ] ++
-+             maybeToList path ++
-              [home </> ".cabal/share/doc" {- Linux -} ]
-     filterM doesDirectoryExist xs
- 
-diff --git a/src/Hoogle/Language/Haskell.hs b/src/Hoogle/Language/Haskell.hs
-index b037f11..f2ac047 100644
---- a/src/Hoogle/Language/Haskell.hs
-+++ b/src/Hoogle/Language/Haskell.hs
-@@ -112,7 +112,7 @@ setPriority pkg mod x = x{itemPriority = pri}
- 
- setModuleURL (Just pkg) _ x | itemLevel x == 1 = x{itemURL=if null $ itemURL x then f $ itemName x else itemURL x}
-     where f xs = if "http://hackage.haskell.org/package/" `isPrefixOf` itemURL pkg
--                 then "http://hackage.haskell.org/packages/archive/" ++ itemName pkg ++ "/latest/doc/html/" ++ file
-+                 then "http://hackage.haskell.org/package/" ++ itemName pkg ++ "/docs/" ++ file
-                  else takeDirectory (itemURL pkg) ++ "/" ++ file
-               where file = reps '.' '-' xs ++ ".html"
- setModuleURL _ _ x = x
diff --git a/pkgs/development/libraries/haskell/hoogle/local.nix b/pkgs/development/libraries/haskell/hoogle/local.nix
index 490898a75b20..ba907948b14a 100644
--- a/pkgs/development/libraries/haskell/hoogle/local.nix
+++ b/pkgs/development/libraries/haskell/hoogle/local.nix
@@ -9,12 +9,12 @@
 #   haskellPackages =
 #     let callPackage = pkgs.lib.callPackageWith haskellPackages;
 #     in pkgs.recurseIntoAttrs (pkgs.haskellPackages.override {
-#         extraPrefs = self: {
+#         extension = self: super: {
 #           hoogleLocal = pkgs.haskellPackages.hoogleLocal.override {
 #             packages = with pkgs.haskellPackages; [
 #               mmorph
 #               monadControl
-#             ]
+#             ];
 #           };
 #         };
 #       });
@@ -23,43 +23,22 @@
 # This will build mmorph and monadControl, and have the hoogle installation
 # refer to their documentation via symlink so they are not garbage collected.
 
-{ cabal, aeson, binary, blazeBuilder, Cabal, caseInsensitive
-, cmdargs, conduit, deepseq, filepath, haskellSrcExts, httpTypes
-, parsec, QuickCheck, random, resourcet, safe, shake, tagsoup, text
-, time, transformers, uniplate, vector, vectorAlgorithms, wai, warp
-, fetchurl
-
-, parallel, perl, wget, rehoo, haskellPlatform
-, packages ? haskellPlatform.propagatedUserEnvPkgs
+{ stdenv, hoogle, rehoo
+, haskellPlatform, ghc, packages ? [ haskellPlatform ghc.ghc ]
 }:
 
-cabal.mkDerivation (self: rec {
-  pname = "hoogle";
-  version = "4.2.32";
-  sha256 = "1rhr7xh4x9fgflcszbsl176r8jq6rm81bwzmbz73f3pa1zf1v0zc";
-  isLibrary = true;
-  isExecutable = true;
-  buildInputs = [self.ghc Cabal] ++ self.extraBuildInputs
-    ++ [ parallel perl wget rehoo ] ++ packages;
-  buildDepends = [
-      aeson binary blazeBuilder Cabal caseInsensitive cmdargs conduit
-      deepseq filepath haskellSrcExts httpTypes parsec QuickCheck random
-      resourcet safe shake tagsoup text time transformers uniplate vector
-      vectorAlgorithms wai warp
-    ];
-  testDepends = [ filepath ];
-  testTarget = "--test-option=--no-net";
+let
+  inherit (stdenv.lib) optional;
+  wrapper = ./hoogle-local-wrapper.sh;
+in
+stdenv.mkDerivation {
+  name = "hoogle-local-0.1";
+  buildInputs = [hoogle rehoo];
 
-  # The tests will fail because of the added documentation.
-  doCheck = false;
-  patches = [ ./hoogle-local.diff
-              (fetchurl { url = "https://github.com/ndmitchell/hoogle/commit/5fc294f2b5412fda107c7700f4d833b52f26184c.diff";
-                          sha256 = "1fn52g90p2jsy87gf5rqrcg49s8hfwway5hi4v9i2rpg5mzxaq3i"; })
-            ];
+  phases = [ "installPhase" ];
 
   docPackages = packages;
-
-  postInstall = ''
+  installPhase = ''
     if [ -z "$docPackages" ]; then
         echo "ERROR: The packages attribute has not been set"
         exit 1
@@ -71,27 +50,38 @@ cabal.mkDerivation (self: rec {
     cd $out/share/hoogle
 
     function import_dbs() {
-        find $1 -name '*.txt' \
-            | parallel -j$NIX_BUILD_CORES 'cp -p {} .; perl -i -pe "print \"\@url file://{//}/index.html\n\" if /^\@version/;" {/}; $out/bin/hoogle convert {/}'
+        find $1 -name '*.txt' | while read f; do
+          newname=$(basename "$f" | tr '[:upper:]' '[:lower:]')
+          if [[ -f $f && ! -f ./$newname ]]; then
+            cp -p $f ./$newname
+            hoogle convert -d "$(dirname $f)" "./$newname"
+          fi
+        done
     }
 
     for i in $docPackages; do
-        import_dbs $i/share/doc
-        ln -sf $i/share/doc/*-ghc-*/* $out/share/hoogle/doc 2> /dev/null \
-            || ln -sf $i/share/doc/* $out/share/hoogle/doc
+        findInputs $i docPackages propagated-native-build-inputs
+        findInputs $i docPackages propagated-build-inputs
     done
 
-    import_dbs ${self.ghc}/share/doc/ghc*/html/libraries
-    ln -sf ${self.ghc}/share/doc/ghc*/html/libraries/* $out/share/hoogle/doc
+    for i in $docPackages; do
+      if [[ ! $i == $out ]]; then
+        for docdir in $i/share/doc/*-ghc-*/* $i/share/doc/*; do
+          if [[ -d $docdir ]]; then
+            import_dbs $docdir
+            ln -sf $docdir $out/share/hoogle/doc
+          fi
+        done
+      fi
+    done
 
-    unset http_proxy
-    unset ftp_proxy
+    import_dbs ${ghc}/share/doc/ghc*/html/libraries
+    ln -sf ${ghc}/share/doc/ghc*/html/libraries/* $out/share/hoogle/doc
 
     chmod 644 *.hoo *.txt
-    $out/bin/hoogle data -d $PWD --redownload -l $(echo *.txt | sed 's/\.txt//g')
-    PATH=$out/bin:$PATH ${rehoo}/bin/rehoo -j4 -c64 .
+    rehoo -j4 -c64 .
 
-    rm -fr downloads *.txt *.dep
+    rm -fr downloads *.dep *.txt
     mv default.hoo x || exit 0
     rm -f *.hoo
     mv x default.hoo || exit 1
@@ -101,23 +91,17 @@ cabal.mkDerivation (self: rec {
         exit 1
     fi
 
-    mv $out/bin/hoogle $out/bin/.hoogle-wrapped
-    cat - > $out/bin/hoogle <<EOF
-    #! ${self.stdenv.shell}
-    COMMAND=\$1
-    shift
-    HOOGLE_DOC_PATH=$out/share/hoogle/doc exec $out/bin/.hoogle-wrapped \$COMMAND -d $out/share/hoogle "\$@"
-    EOF
+    mkdir -p $out/bin
+    substitute ${wrapper} $out/bin/hoogle \
+        --subst-var out --subst-var-by shell ${stdenv.shell} \
+        --subst-var-by hoogle ${hoogle}
     chmod +x $out/bin/hoogle
   '';
 
   meta = {
-    homepage = "http://www.haskell.org/hoogle/";
-    description = "Haskell API Search";
-    license = self.stdenv.lib.licenses.bsd3;
-    platforms = self.ghc.meta.platforms;
-    maintainers = [ self.stdenv.lib.maintainers.jwiegley ];
-    hydraPlatforms = self.stdenv.lib.platforms.none;
-    broken = true;
+    description = "A local Hoogle database";
+    platforms = ghc.meta.platforms;
+    hydraPlatforms = with stdenv.lib.platforms; none;
+    maintainers = with stdenv.lib.maintainers; [ ttuegel ];
   };
-})
+}
diff --git a/pkgs/top-level/haskell-packages.nix b/pkgs/top-level/haskell-packages.nix
index 63eba9d9ea3e..942e4be2ca7a 100644
--- a/pkgs/top-level/haskell-packages.nix
+++ b/pkgs/top-level/haskell-packages.nix
@@ -1234,9 +1234,7 @@ self : let callPackage = x : y : modifyPrio (newScope self x y); in
   hoodleTypes = callPackage ../development/libraries/haskell/hoodle-types {};
 
   hoogle = callPackage ../development/libraries/haskell/hoogle {};
-  hoogleLocal = callPackage ../development/libraries/haskell/hoogle/local.nix {
-    parallel = pkgs.parallel;
-  };
+  hoogleLocal = callPackage ../development/libraries/haskell/hoogle/local.nix {};
 
   hopenssl = callPackage ../development/libraries/haskell/hopenssl {};