Search code examples
haskellcabalnixos

How to preserve purity in local nix build


I have read Oliver Charles' article titled "How I Develop with Nix". Now I too would like to use Nix for my Haskell development. However, one thing that puzzled me a bit was the description of the local nix build script:

{ haskellPackages ? (import <nixpkgs> {}).haskellPackages }:
let
  inherit (haskellPackages) cabal cabalInstall_1_18_0_2
    text mtl transformers; # Haskell dependencies here

in cabal.mkDerivation (self: {
  pname = "project-name";
  version = "1.0.0";
  src = ./.;
  buildDepends = [
    # As imported above
    text mtl transformers
  ];
  buildTools = [ cabalInstall_1_18_0_2 ];
  enableSplitObjs = false;
})

(Source: The article cited above)

If I am not mistaken, Nix makes guarantees like binary substitution by deriving a hash from the attribute set passed to the function. However, in this case there is no versioning associated with the src attribute. Thus, I'd think that locally modifying my code would mean different compilation results are associated with the same hash. Does that not break the guarantees made by Nix? Is Nix clever enough to detect changes to the file system (by looking at timestamps for instance)?


Solution

  • Each time you invoke nix-shell it will compute the hash of whats currently in src and copy it to the nix store under the hash name if it doesn't already exist. So changed src content will lead to a new hash in the end. This is true for all paths in the derivation attribute set; They are all copied to the nix store.

    Of course the same thing happens when you do a proper install.