numtide / nix-filter

a small self-contained source filtering lib

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to use nix-filter for a path returned by gitignore.nix ?

doronbehar opened this issue · comments

I'd like to ignore both everything that's in my .gitignore with gitignore.nix and afterwards exclude more files with nix-filter.

I tried:

        src = nix-filter {
          root = gitignoreSource ./.;
        };

But that failed with:

error: assertion '((builtins).isPath  root)' failed

At:

assert builtins.isPath root;

And I also tried:

src = nix-filter {
  root = builtins.path {
    path = gitignoreSource ./.;
  };

But that failed with:

error: string '/nix/store/r1r5ibqn3rh3mklzjb8l196ibxz42rrv-source' cannot refer to other paths

I also tried to first use gitignoreSource and afterwards nix-filter, but that failed similarly.

I noticed there's this open issue and I tried to help that by exposing a makeFilter function from this library, but I noticed all functions rely upon an argument root which is the full path to the source.

Any ideas?

I used eventually something similar to what's used here: hercules-ci/gitignore.nix#9 (comment)

I'd like to ignore both everything that's in my .gitignore with gitignore.nix and afterwards exclude more files with nix-filter.

I tried:

        src = nix-filter {
          root = gitignoreSource ./.;
        };

But that failed with:

error: assertion '((builtins).isPath  root)' failed

I think this is because gitignoreSource uses lib.cleanSourceWith internally and lib.cleanSourceWith uses toSourceAttributes which in turn calls fromSourceAttributes and that returns a custom attribute set, not a Nix path. Basically, "nixpkgs/lib/sources.nix" has an internal source filtering logic and gitignoreSource depends on that.

And I also tried:

src = nix-filter {
  root = builtins.path {
    path = gitignoreSource ./.;
  };

But that failed with:

error: string '/nix/store/r1r5ibqn3rh3mklzjb8l196ibxz42rrv-source' cannot refer to other paths

See the second problem described in this. You should be able to circumvent the problem with builtins.unsafeDiscardStringContext, But:

I think a better solution would be to stop using gitignore et al. and just use this library. From README:

A cool way to include only what you need.

[emphasis added]
Note that the library supports excluding paths but I think the main idea is to include what you need.

The main workaround is to use either builtins.fetchGit ./. or one of the many gitignore filter projects but this is not precise enough. If the project README changes, it should rebuild the project. If the nix code changes, it shouldn't rebuild the project. That's why this project exists. I want total control.

And to achieve total control you need to use whitelisting and explicitly specify the paths you want to pass the filter, not the other way around.

I have been using src values similar to this:

  src = nix-filter {
    root = ./..;
    include = [
      "Cargo.lock"
      "Cargo.toml"
      (inDirectory "src")
      (inDirectory "test")
    ];
    name = pname;
  };

for a while and I didn't encounter any problems and unexpected behaviour (apart from the ones in the linked comment, but those are problems with Nix).

I understand now. Thanks! I won't mind to close this issue, but here's a suggestion to the README: #12

I'd like to ignore both everything that's in my .gitignore with gitignore.nix and afterwards exclude more files with nix-filter.

I tried:

        src = nix-filter {
          root = gitignoreSource ./.;
        };

But that failed with:

error: assertion '((builtins).isPath  root)' failed

So gitignoreSource returns something like the below

{ _isLibCleanSourceWith = true; filter = «lambda @ /nix/store/dizbqa4nym7h5xw3s027gpjngxmm14fb-source/lib/sources.nix:92:16»; name = "source"; origSrc = <...>; outPath = "/nix/store/lfvadyi4d1z1h93k087hdf6bif1q1vn3-source"; }

But even with gitignoreSource.outPath it is still not a path, but a string with context. I encountered this problem when I tried to use nix-filter on a flake input. Flake inputs also exposes an outPath attribute, similar to above. I wasn't expecting the source filtering to work but for a different reason (second Nix error described in here). I am not sure why this library requires root to be a path. Maybe it is to avoid this Nix error.