let
  pinned-pkgs = import ./nixpkgs.nix { };
in
{ pkgs ? pinned-pkgs, lib ? pkgs.lib, python ? pkgs.python3 }:
let
  tools = pkgs.callPackage ./tools {};
in
pkgs.mkShell {
  # When a path (such as `pkgs.path`) is interpolated into a string then nix
  # first adds that path to the store, and then interpolates the store path
  # into the string.  We use `builtins.toString` to convert the path to a
  # string without copying it to the store before interpolating. Either the
  # path is already in the store (e.g. when `pkgs` is `pinned-pkgs`) so we
  # avoid making a second copy with a longer name, or the user passed in local
  # path (e.g. a checkout of nixpkgs) and we point at it directly, rather than
  # a snapshot of it.
  # See https://github.com/NixOS/nix/issues/200 and https://github.com/NixOS/nix/issues/1728
  shellHook = ''
    export NIX_PATH="nixpkgs=${builtins.toString pkgs.path}";
  '';
  # Run the shellHook from tools
  inputsFrom = [tools];
  buildInputs = [
    tools
    pkgs.morph
    pkgs.jp
  ];
}