`src = ../folder`: Source is not taken relative to current directory but relative to `/nix/store`

Hello,

I just wrote the following haskellPackage overwrite file (named hpkgs.nix), in order to compile Hakyll with a different source, located in ../hakyll (relative to the root folder). To do that, I put a line (flip overrideSrc {src = ../hakyll; } (see the whole code at the end of the post). When I compile with:

nix-build -E "let pkgs = import <nixpkgs> {}; haskellPackages' = pkgs.callPackage ./hpkgs.nix {}; in haskellPackages'.hakyll"

it works fine (well at least it finds the source). However, if I use the flake version flake.nix file:

{
  description = "";
  ###### Inputs
  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
  inputs.flake-utils.url = "github:numtide/flake-utils";
  ###### Outputs
  outputs = { self, nixpkgs, flake-utils }:
    # See https://github.com/numtide/flake-utils
    flake-utils.lib.eachDefaultSystem
      (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
          haskellPackages' = pkgs.callPackage ./hpkgs.nix {};
          myShell = pkgs.mkShell {
            buildInputs = [
              (haskellPackages'.ghcWithPackages (p: [p.hakyll]))
            ];
          };
        in
        rec {
          devShell = myShell;
        });
}

It fails with an error:

access to path '/nix/store/hakyll' is forbidden in restricted mode

So I guess that the whole folder is copied in the store and then it tries to look at the path of ../, hence the error… Is it a feature to enforce purity or a bug? Is there a way to avoid that without copying the source inside my project ? Ideally I’d prefer not to change my flake.nix, but I also tried to add an input via inputs.hakyll-src = {url = "../hakyll"; flake = false; }; but it fails with an error:

$ nix develop 
flake reference '../hakyll' is not an absolute path

Code:

# hpkgs.nix

{ compiler ? "ghc884"
, pkgs
}:

let
  inherit (pkgs.lib.trivial) flip pipe;
  inherit (pkgs.haskell.lib) appendPatch appendConfigureFlags;

  hakyllFlags = [ "-f" "watchServer" "-f" "previewServer" ];

  haskellPackages = pkgs.haskell.packages.${compiler}.override {
    overrides = hpNew: hpOld: {
      hakyll =
        # pipe is used to apply all the following rules
        # sequentially in order to override the initial hpOld.hakyll derivation
        pipe
          hpOld.hakyll
          (with pkgs.haskell.lib; [
            # See the file pkgs/development/haskell-modules/lib.nix for a list of such functions:
            # (flip appendPatch ./hakyll.patch)
            # We force the above flags, since cabal may silently disable them if a dependency is missing
            (flip appendConfigureFlags hakyllFlags)
            unmarkBroken
            # doJailbreak
            # To do tests:
            (flip overrideSrc {src = ../hakyll; })
          ]);

      # ...
    };
  };
in haskellPackages
1 Like

Flakes get copied to the store before evaluation. And only what is at least added to guts staging area will be considered when copying.

This is a known feature/limitation of flakes. It ensures purity/hermeticity.

Ok thank you. But why is it also impossible to specify a (relative) path in the inputs? If I can specify a url with something like:

  inputs.uikit-src = {
    url = "github:uikit/uikit/v3.5.9";
    flake = false;
  };

I would expect to be able to specify a folder no? And then there shouldn’t be any reason for forcing the path to be absolute I guess.