numtide / nix-filter

a small self-contained source filtering lib

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

#27 breaks when using flakes with error: access to absolute path '/nix/store' is forbidden

dbarrosop opened this issue · comments

Describe the bug

Since #27 this seems to break with flakes. If you add a check like

       ...
        nix-src = nix-filter.lib.filter {
          root = ./.;
          include = [
             (nix-filter.lib.matchExt "nix")
          ];
        };
       ...

        checks = flake-utils.lib.flattenTree {

          nixpkgs-fmt = pkgs.runCommand "check-nixpkgs-fmt"
            {
              buildInputs = with pkgs; [
                nixpkgs-fmt
              ];
            }
            ''
              mkdir $out
              # nixpkgs-fmt --check ${nix-src}
            '';
      ...

And then try to run nix flake check it breaks with:

nix flake check --print-build-logs --show-trace
warning: Git tree '/Users/dbarroso/workspace/nhost/be' is dirty
error: access to absolute path '/nix/store' is forbidden in pure eval mode (use '--impure' to override)

       … while realising the context of path '/nix/store'

       at /nix/store/klvk2xb6g11rkfpf1y10aln7jyd23a38-source/default.nix:156:9:

          155|     builtins.pathExists p
          156|     && (builtins.readDir (builtins.dirOf p)).${builtins.baseNameOf p} == "directory";
             |         ^
          157| }

       … while evaluating '_pathIsDirectory'

       at /nix/store/klvk2xb6g11rkfpf1y10aln7jyd23a38-source/default.nix:154:22:

          153|   # Returns true if the path exists and is a directory and false otherwise
          154|   _pathIsDirectory = p:
             |                      ^
          155|     builtins.pathExists p

       … from call site

       at /nix/store/klvk2xb6g11rkfpf1y10aln7jyd23a38-source/default.nix:20:14:

           19|     }:
           20|       assert _pathIsDirectory root;
             |              ^
           21|       let

       … while evaluating 'filter'

       at /nix/store/klvk2xb6g11rkfpf1y10aln7jyd23a38-source/default.nix:8:5:

            7|   filter =
            8|     {
             |     ^
            9|       # Base path to include

       … from call site

       at /nix/store/bkmqpzqyyka3qjs1cs9x6r8pp9kpx5fh-source/flake.nix:23:19:

           22|
           23|         nix-src = nix-filter.lib.filter {
             |                   ^
           24|           root = ./.;

       … while evaluating the attribute 'buildCommand' of the derivation 'check-nixpkgs-fmt'

       at /nix/store/vns9ic8pgb1dx7cfmg3ivyxz73yn92nh-source/pkgs/stdenv/generic/make-derivation.nix:270:7:

          269|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          270|       name =
             |       ^
          271|         let

       … while checking the derivation 'checks.aarch64-linux.nixpkgs-fmt'

       at /nix/store/nbkbs33bkw54f60kv5c5y48714l00dpw-source/flattenTree.nix:16:9:

           15|       (sum // {
           16|         "${pathStr}" = val;
             |         ^
           17|       })

       … while checking flake output 'checks'

       at /nix/store/nbkbs33bkw54f60kv5c5y48714l00dpw-source/default.nix:137:17:

          136|               {
          137|                 ${key} = (attrs.${key} or { })
             |                 ^
          138|                   // (appendSystem key system ret);

To Reproduce

See above.

Expected behavior

It should work

System information

Using 825abbb, if you revert to the previous commit it works fine.

Additional context

N/A

/cc @ilkecan

It smells like a string interpolation forcing a path to get added to the store.

Also builtins.readDir on /nix/store is likely pretty slow.

Currently there isn't any Nix builtin to determine if a path is a directory or not. Before #27 _pathIsDirectory was defined as:

 # Returns true if the path exists and is a directory, throws an error otherwise
_pathIsDirectory = p: builtins.pathExists p && builtins.isAttrs (builtins.readDir p);

We were calling _pathIsDirectory with paths that were suppose to be a directory so defining it as a partial function like this was somewhat OK.

But to implement #27, I needed a total version of _pathIsDirectory so I had the idea of using builtins.readDir on the parent of the path, because it also returns the type of the children.

But I didn't think/test about this specific case of root = ./.; with flakes. Accessing the parent directory of a flake (/nix/store/1) is not allowed which this assertion do:

assert _pathIsDirectory root;

#30 should fix this by reintroducing the old definition under a different name and using that for the assertions.

Footnotes

  1. because flake evaluations happens on files after they are copied to the Nix store

fixed in #31. Thanks!