Search code examples
haskellnix

How can I add a Haskell package from GitHub to my shell.nix file?


So I have a Haskell project that has a shell.nix that looks like this:

{ nixpkgs ? import <nixpkgs> {} }:
let
  inherit (nixpkgs) pkgs;
  ghc = pkgs.haskellPackages.ghcWithPackages (ps: with ps; [
    regex-compat lucid replace-attoparsec hspec cabal-install text-regex-replace optparse-generic lens-regex-pcre clay bytestring charsetdetect AhoCorasick
  ]);
in
pkgs.stdenv.mkDerivation {
  name = "my-haskell-env";
  buildInputs = [ ghc ];
  shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
}

But AhoCorasick is broken, and I need to install a custom version of it, from here:

https://github.com/stackbuilders/AhoCorasick

How do I do that? I imagine it's something using pkgs.fetchFromGitHub, but I can't even seem to find documentation for this in the Nix manuals.

Edit: here's what I'm trying so far:

{ nixpkgs ? import <nixpkgs> {} }:
let
  inherit (nixpkgs) pkgs;
  myAhoCorasickSrc = pkgs.fetchFromGitHub {
    owner = "stackbuilders";
    repo  = "AhoCorasick";
    rev = "cbf76b78612c66e51eb02f24162ace49325c5d61";
    sha256 = "0ci5rywh042yi4ild3i7kx09rmj5v5iswzsah47f8axj1kq5vlci";
  };
  myAhoCorasick = pkgs.haskellPackages.callCabal2nix myAhoCorasickSrc {};
  ghc = pkgs.haskellPackages.ghcWithPackages (ps: with ps; [
    regex-compat
    lucid
    replace-attoparsec
    hspec
    cabal-install
    text-regex-replace
    optparse-generic
    lens-regex-pcre
    clay
    bytestring
    charsetdetect
    myAhoCorasick
  ]);
in
pkgs.stdenv.mkDerivation {
  name = "my-haskell-env";
  buildInputs = [ ghc ];
  shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
}

What's strange is that it just seems to return a shell, but the package is missing. What am I doing wrong?


Solution

  • You need to weave your package into the haskellPackages set:

    { nixpkgs ? import <nixpkgs> {} }:
    let
      inherit (nixpkgs) pkgs;
      myAhoCorasickSrc = pkgs.fetchFromGitHub {
        owner = "stackbuilders";
        repo  = "AhoCorasick";
        rev = "cbf76b78612c66e51eb02f24162ace49325c5d61";
        sha256 = "0ci5rywh042yi4ild3i7kx09rmj5v5iswzsah47f8axj1kq5vlci";
      };
    
      myHaskellPackages = pkgs.haskellPackages.override {
        overrides = self: super: with pkgs.haskell.lib; {
          AhoCorasick = super.callCabal2nix "AhoCorasick" myAhoCorasickSrc {};
    
          clay = doJailbreak (unmarkBroken super.clay);
    
          replace-attoparsec = super.callHackageDirect {
            pkg = "replace-attoparsec";
            ver = "1.2.0.0";
            sha256 = "0vgvrcv1inf90s620f48ixikpb9rfffq0mc1fxg7ffi8c0sijc2n";
          } {};
        };
      };
    
      ghc = myHaskellPackages.ghcWithPackages (ps: with ps; [
        regex-compat
        lucid
        replace-attoparsec
        hspec
        cabal-install
        text-regex-replace
        optparse-generic
        lens-regex-pcre
        clay
        bytestring
        charsetdetect
        AhoCorasick
      ]);
    in
    pkgs.mkShell {
      name = "my-haskell-env";
      buildInputs = [ ghc ];
    }
    

    (Also, replace-attoparsec was not present in my nixpkgs, so I had to add that, and clay was marked broken because its bounds were too narrow for the hspec/hspec-discover in my nixpkgs.)