Building Haskell projects from GitHub in NixOS packages

Hello

I have been trying to get into developing Haskell programs on NixOS. I am trying to create a Nix package for an existing project (a fork of pandoc-theorem) on GitHub and use it in a shell.nix. But I have run into issues. So, I am posting here in hope that someone with NixOS experience can point be in the right direction.

My understanding is that I need a Nix Expression for this program which uses pkgs.haskellPackages.developPackage along with pkgs.fetchFromGitHub to fetch and build this for the shell. This expression will be put in a file, then the shell.nix file imports this expression and adds it the buildInputs parameter of of mkShell.

I have created the two files, and attempted to nix-shell to test that I get access to the tool. I can build using nix-build, which creates the compiled executable and puts it in the “result” directory. But I wanted to bundle this package together with a whole set for a project using nix-shell.

Unfortunately running nix-shell fails with the error:

bash: /nix/store/1pbyswvdf5q4yrm4qjkk15ij0fi3bs6c-ghc-9.4.8-with-packages: Is a directory
bash: pop_var_context: head of "shell_variables" is not a function context
bash: pop_var_context: head of "shell_variables" is not a function context

What is the source of this error? I must have misunderstood something about how to build the Haskell project and import into nix-shell, but I don’t really know where to start unwinding this. I have included the details below. In advance, thanks for any pointers in the right direction.

Listings

pandoc-theorem.nix:

{ pkgs ? import <nixpkgs> {} } :
let
  pandocTheoremSrc = pkgs.fetchFromGitHub {
    owner = "typeterrorist";
    repo = "pandoc-theorem";
    rev = "d2fc223f";
    sha256 = "sha256-rvS+pZro3KkFgdgBxKkVDeJJa8WW2zk59ExooIAb7C0=";
    };
in
 pkgs.haskellPackages.developPackage {
  name = "pandoc-theorem";
  root = pandocTheoremSrc;
  modifier = drv:
      pkgs.haskell.lib.addBuildTools drv (with pkgs.haskellPackages;
        [ cabal-install
          ghcid
        ]);
}

shell.nix:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = [
    (import ./pandoc-theorem.nix { inherit pkgs; })
  ];
}

Attempting to run nix-shell in the directory with shell.nix and pandoc-theorem.nix in it:

$ nix-shell
bash: /nix/store/1pbyswvdf5q4yrm4qjkk15ij0fi3bs6c-ghc-9.4.8-with-packages: Is a directory
bash: pop_var_context: head of "shell_variables" is not a function context
bash: pop_var_context: head of "shell_variables" is not a function context
1 Like

developPackage already returns a shell derivation, so it should suffice to return it from shell.nix:

{ pkgs ? import <nixpkgs> {} }:
import ./pandoc-theorem.nix { inherit pkgs; }

Thank you for the suggestion, catachresthetic.

What does it meant that it returns a shell derivation?

If I replace shell.nix with your suggestion the shell starts, but the program is not in PATH at least:

$ nix-shell
$ pandoc-theorem-exe
pandoc-theorem-exe: command not found

Even though it is in the result/bin folder when I build it.

developPackage returns a shell environment suitable for developing the package mentioned, if you want to compile the package and have it in your PATH, you need to use cabal2nix to get a nix derivation and then install it to a development shell, you probably will find callCabal2nix useful, luckily it is now documented on the nixpkgs manual

1 Like

Thank you, eldritch-cookie! This seems to be what I want. I will try this out.