makeSetupHook and shell.nix

I just discovered makeSetupHook and an interesting use for it in shell.nix files.

In a few projects, I had shell.nix files that used shellHook to run helper scripts I’d tucked away in a ./nix subdirectory.

For example, in a few cases I wanted to spin up a database upon entering the shell and spin it down upon exiting:

{ pkgs ? import <nixpkgs> {} }:

with pkgs; mkShell {
  name = "foo";
  buildInputs = [ postgresql ];
  shellHook = ''
    trap "'$PWD/nix/pgSetup' remove" EXIT

One problem with this approach is it relies on the presence of these random shell scripts that are not represented as part of the derivation itself. Another problem is that I end up duplicating these scripts across projects.

I was going to address this by packing the helper scripts with writeShellScript, but then I noticed makeSetupHook. It sounds like it was designed with a different use-case in mind, but it lets me package the setup script and automatically runs it upon entering the shell as long as I include it in my buildInputs:

{ pkgs ? import <nixpkgs> {} }:

  pgSetup = with pkgs; makeSetupHook { } ./nix/pgSetup;

in with pkgs; mkShell {
  name = "foo";
  buildInputs = [ postgresql pgSetup ];
  shellHook = ''
    trap '${pgSetup}/nix-support/setup-hook remove' EXIT

So ./nix/pgSetup needs to exist relative to the derivation, but it doesn’t need to exist relative to nix-shell invocation, allowing, for example, using it like:

nix-shell -A foo

I might actually switch to using writeShellScript, as it offers more flexibility and control, but I thought this was interesting.


Would you post your $PWD/nix/pgSetup? I am trying to create mongoSetup


with import <nixpkgs> {};
  mongoSetup = makeSetupHook { } ./nix/;
in mkShell {

	buildInputs = [

	shellHook = ''
		echo starting mongod in the current dir.
		echo 'mongod --dbpath $PWD/data > mongod.log'
		trap '${mongoSetup}/nix-support/setup-hook remove' EXIT




mkdir -p data
mongod --dbpath data > mongod.log

But this is does not spin up the mongod as it does not kill with trap.