• Stars
    star
    194
  • Rank 198,646 (Top 4 %)
  • Language
    Nix
  • License
    MIT License
  • Created over 3 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

a small self-contained source filtering lib

logo
nix-filter - a small self-contained source filtering lib

STATUS: beta

When using nix within a project, developers often use src = ./.; for a project like this:

{ stdenv }:
stdenv.mkDerivation {
  name = "my-project";
  src = ./.;
}

This works but has an issue; on each build, nix will copy the whole project source code into the /nix/store. Including the .git folder and any temporary files left over by the editor.

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 not rebuild the project. If the nix code changes, it should not rebuild the project.

This project is a small library that makes it easy to filter in and out what files should go into a nix derivation.

Example usage

nix-filter works best for projects where the files needed for a build are easy to match. Using it with only an exclude argument will likely not reduce the reasons for rebuilds by a lot. Here's an Example:

{ stdenv, nix-filter }:
stdenv.mkDerivation {
  name = "my-project";
  src = nix-filter {
    root = ./.;
    # If no include is passed, it will include all the paths.
    include = [
      # Include the "src" path relative to the root.
      "src"
      # Include this specific path. The path must be under the root.
      ./package.json
      # Include all files with the .js extension
      (nix-filter.matchExt "js")
    ];

    # Works like include, but the reverse.
    exclude = [
      ./main.js
    ];
  };
}

Usage

Import this folder. Eg:

let
  nix-filter = import ./path/to/nix-filter;
in
 # ...

The top-level is a functor that takes:

  • root of type path: pointing to the root of the source to add to the /nix/store.
  • name of type string (optional): the name of the derivation (defaults to "source")
  • include of type list(string|path|matcher) (optional): a list of patterns to include (defaults to all).
  • exclude of type list(string|path|matcher) (optional): a list of patterns to exclude (defaults to none).

The include and exclude take a matcher, and automatically convert the string and path types to a matcher.

The matcher is a function that takes a path and type and returns true if the pattern matches.

The flake usage is like this:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
    nix-filter.url = "github:numtide/nix-filter";
  };
  outputs = { self, nixpkgs, nix-filter }:
    let
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
      # Avoid calling it nix-filter as it may result in an infinite recursion
      filter = nix-filter.lib;
     # ....
    in
    {
      # ...
    };
}

Builtin matchers

The functor also contains a number of matchers:

  • nix-filter.matchExt: ext -> returns a function that matches the given file extension.
  • nix-filter.inDirectory: directory -> returns a function that matches a directory and any path inside of it.
  • nix-filter.isDirectory: matches all paths that are directories

Combining matchers

  • and: a -> b -> c combines the result of two matchers into a new matcher.
  • or_: a -> b -> c combines the result of two matchers into a new matcher.

NOTE: or is a keyword in nix, which is why we use a variation here.

REMINDER: both, include & exlude already XOR elements, so or_ is not useful at the top level.

Design notes

This solution uses builtins.path { path, name, filter ? path: type: true } under the hood, which ships with Nix.

While traversing the filesystem, starting from path, it will call filter on each file and folder recursively. If the filter returns false then the file or folder is ignored. If a folder is ignored, it won't recurse into it anymore.

Because of that, it makes it difficult to implement recursive glob matchers. Something like **/*.js would necessarily have to add every folder, to be able to traverse them. And those empty folders will end-up in the output.

If we want to control rebuild, it's important to have a fixed set of folders.

One possibility is to use a two-pass system, where first all the folders are being added, and then the empty ones are being filtered out. But all of this happens at Nix evaluation time. Nix evaluation is already slow enough like that.

That's why nix-filter is asking the users to explicitly list all the folders that they want to include, and using only an exclude is not recommended.

Future development

Add more matchers.

Related projects

License

Copyright (c) 2021 Numtide under the MIT.

More Repositories

1

devshell

Per project developer environments
Nix
1,213
star
2

flake-utils

Pure Nix flake utility functions [maintainer=@zimbatm]
Nix
1,126
star
3

system-manager

Manage system config using nix on any distro
Rust
651
star
4

treefmt

one CLI to format your repo [maintainers=@zimbatm,@brianmcgee]
Go
571
star
5

treefmt-nix

treefmt nix configuration
Nix
226
star
6

nixpkgs-unfree

nixpkgs with the unfree bits enabled
Nix
89
star
7

nits

Nix & NATS
Go
78
star
8

nix-gl-host

Run OpenGL/Cuda programs built with Nix, on all Linux distributions.
Python
77
star
9

systemd-vaultd

Provide access to vault secrets to systemd services
Nix
63
star
10

nixos-facter

Declarative nixos-generate-config [maintainer=@brianmcgee]
Go
48
star
11

blueprint

Nix without the glue code
Nix
39
star
12

nix-vm-test

Re-use the NixOS VM test infrastructure to test Ubuntu, Debian, and Fedora machines.
Nix
33
star
13

nar-serve

Unpack and serve NAR file content on the fly
Go
30
star
14

bld

Build nix targets based on git repository directories
Go
29
star
15

prj-spec

Project Base Directory Specification
Shell
28
star
16

terraform-provider-linuxbox

Configure Linux machines with Terraform
Go
28
star
17

deploykit

Execute commands remote via ssh and locally in parallel with python
Python
27
star
18

nix-stdlib

experimental nix prelude
Nix
25
star
19

action-cli

GitHub Actions without JavaScript
Rust
19
star
20

nix-eval-cache

Skips build/evaluation based on modification date of nix files.
Rust
18
star
21

software-consulting-documents

Software Consulting Legal Documents
16
star
22

zero-to-odoo

Nix
15
star
23

github-deploy

Track deployments on GitHub PRs
Go
13
star
24

clean-git-action

Leave no build artifacts behind
Shell
11
star
25

serve-go

Like vercel/serve but for production. Serve SPA apps quickly.
Go
10
star
26

build-go-cache

buildGoCache speeds up nix's buildGoModule by pre-compiling imported go modules
Nix
10
star
27

nixos-rke2

NixOS modules for RKE2
Nix
9
star
28

nix-gitignore

filterSource using .gitignore (experiment)
Go
7
star
29

numtide-github-runner

the best self-hosted github runners on the market
Nix
7
star
30

terraform-deploy-nixos-flakes

Shell
6
star
31

nixos-facter-modules

A series of NixOS modules to be used in conjunction with https://github.com/numtide/nixos-facter [maintainer=@brianmcgee]
Nix
5
star
32

terraform-upload-ami

Upload and import the AMI from a VHD
HCL
5
star
33

generate-terraform-provider-shim

Handle third-party Terraform providers
Go
4
star
34

harvest-invoice-calculator

A little tool that helps generating invoices from Harvest data
Python
4
star
35

configure-nix-action

Configures Nix on GitHub Actions
Shell
4
star
36

terraform-nixos-install

HCL
3
star
37

nixpkgs-terraform

terraform-related packages with Nix
Nix
3
star
38

gh-v6.com

GitHub downloads, with IPv6
HTML
3
star
39

kartusche

Go
2
star
40

terraform-nix-build

Build Nix with the external provider
Python
2
star
41

terraform-linuxbox-traefik

HCL
2
star
42

terraform-linuxbox-monitorpack

Seed DevOps monitoring module
HCL
2
star
43

activate

A small resource converger tool
Nix
2
star
44

mkdocs-numtide

Our own mkdocs template, based on the material design
Nix
2
star
45

docker-host-forwarder

Docker image that will forward udp/tcp to docker host
Shell
2
star
46

nix-vm-test-demo

Dump of the code used in the nix-vm-test demo
Nix
2
star
47

terraform-nixos-amis

Fork of https://github.com/tweag/terraform-nixos/tree/master/aws_image_nixos
HCL
2
star
48

nixionary.org

HTML
2
star
49

NixOS-Fleet-Update-Provider

Terraform provider to update a homogeneous NixOS fleet configuration
Shell
2
star
50

yarnlock2json

Convert `yarn.lock` files to JSON
JavaScript
1
star
51

cert-wizard

Go
1
star
52

nixos-facter-docs

Documentation for NixOS Facter and NixOS Facter Modules
Nix
1
star
53

treefmt-docs

Treefmt Docs
Nix
1
star
54

.github

GitHub Settings for the org
1
star