I’ve mixed many ideas from tutorials (like haskell-nix & nix-haskell-monorepo) and approaches posted here, so this is my setup for nix-shell
development as of now:
- Pin a working version of nixpkgs-channels with the nix-prefetch-git command, save the output as a
json
file.
$ nix-prefetch-git --rev 8d1510abfb592339e13ce8f6db6f29c1f8b72924 https://github.com/NixOS/nixpkgs-channels.git > .nixpkgs-version.json
Create a pinned-nixpkgs.nix
file to load the json
file and return our chosen version of nixpkgs
:
{ bootstrap ? import <nixpkgs> {}
, json ? ./.nixpkgs-version.json
}:
let
nixpkgs = builtins.fromJSON (builtins.readFile json);
src = bootstrap.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs-channels";
inherit (nixpkgs) rev sha256;
};
in
import src {}
- (OPTIONAL) Create a
defaul.nix
. This one is my default for a simple Haskell project, for Python it would be something likebuildPythonApplication
. Also, it’s good to usenix-gitignore
(or other similar tools) to prevent unwanted files/folders to be part of thenix-build/nix-shell
(specially if you plan to use step 4).
{ pkgs ? import ./pinned-nixpkgs.nix {} }:
let
gitignore = pkgs.nix-gitignore.gitignoreSource [] ./.;
in
pkgs.haskellPackages.callCabal2nix "<project-name>" gitignore {}
- Write a
shell.nix
file that uses your pinned version ofnixpkgs
, if adefault.nix
is present, then override it some extra dependencies that might be useful while developing your package.
let
pkgs = import ./pinned-nixpkgs.nix {};
dev-pkgs = with pkgs.haskellPackages; [
cabal2nix
cabal-install
ghcid
stylish-haskell
hindent
hlint
];
in
(import ./default.nix {}).overrideAttrs (old: {
buildInputs = old.buildInputs ++ dev-pkgs;
})
- (OPTIONAL, but extremely useful) Use direnv with the Persistent cached shell created by @Mic92. This is one easy way to your shell from being garbage collected, you can still delete a cached env by running
rm .direnv/env-*
.
Change the last line from:
use_nix -s shell.nix -w .nixpkgs-version.json
to
use_nix -s shell.nix
then
$ direnv allow