{"id":13837883,"url":"https://github.com/numtide/nix-filter","last_synced_at":"2025-08-13T06:07:38.721Z","repository":{"id":39741703,"uuid":"360873628","full_name":"numtide/nix-filter","owner":"numtide","description":"a small self-contained source filtering lib","archived":false,"fork":false,"pushed_at":"2024-11-13T21:28:58.000Z","size":63,"stargazers_count":219,"open_issues_count":9,"forks_count":19,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-07-29T03:05:09.003Z","etag":null,"topics":["buildbot-numtide","nix"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/numtide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-23T12:16:46.000Z","updated_at":"2025-07-02T14:03:12.000Z","dependencies_parsed_at":"2024-12-04T03:02:36.881Z","dependency_job_id":"0be61c8a-1a4e-4968-aedc-b9fe95597277","html_url":"https://github.com/numtide/nix-filter","commit_stats":{"total_commits":55,"total_committers":12,"mean_commits":4.583333333333333,"dds":"0.49090909090909096","last_synced_commit":"f7653272fd234696ae94229839a99b73c9ab7de0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/numtide/nix-filter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numtide%2Fnix-filter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numtide%2Fnix-filter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numtide%2Fnix-filter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numtide%2Fnix-filter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/numtide","download_url":"https://codeload.github.com/numtide/nix-filter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numtide%2Fnix-filter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270191419,"owners_count":24542270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["buildbot-numtide","nix"],"created_at":"2024-08-04T15:01:29.258Z","updated_at":"2025-08-13T06:07:38.316Z","avatar_url":"https://github.com/numtide.png","language":"Nix","funding_links":[],"categories":["Nix","Development"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# nix-filter\n\n\u003cimg src=\"nix-filter.svg\" height=\"150\"/\u003e\n\n**small self-contained source filtering lib **\n\n*A \u003ca href=\"https://numtide.com/\"\u003enumtide\u003c/a\u003e project.*\n\n\u003cp\u003e\n\u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/Status-beta-orange\"\u003e\n\u003ca href=\"https://github.com/numtide/nix-filter/actions/workflows/nix.yml\"\u003e\u003cimg src=\"https://github.com/numtide/nix-filter/actions/workflows/nix.yml/badge.svg\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://app.element.io/#/room/#home:numtide.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/Support-%23numtide-blue\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/div\u003e\n\nWhen using nix within a project, developers often use `src = ./.;` for a\nproject like this:\n\n```nix\n{ stdenv }:\nstdenv.mkDerivation {\n  name = \"my-project\";\n  src = ./.;\n}\n```\n\nThis works but has an issue; on each build, nix will copy the whole project\nsource code into the /nix/store. Including the `.git` folder and any temporary\nfiles left over by the editor.\n\nThe main workaround is to use either `builtins.fetchGit ./.` or one of the\nmany gitignore filter projects but this is not precise enough. If the\nproject README changes, it should not rebuild the project. If the nix code\nchanges, it should not rebuild the project.\n\nThis project is a small library that makes it easy to filter in and out what\nfiles should go into a nix derivation.\n\n## Example usage\n\nnix-filter works best for projects where the files needed for a build are easy\nto match. Using it with only an `exclude` argument will likely not reduce the\nreasons for rebuilds by a lot. Here's an Example:\n\n```nix\n{ stdenv, nix-filter }:\nstdenv.mkDerivation {\n  name = \"my-project\";\n  src = nix-filter {\n    root = ./.;\n    # If no include is passed, it will include all the paths.\n    include = [\n      # Include the \"src\" path relative to the root.\n      \"src\"\n      # Include this specific path. The path must be under the root.\n      ./package.json\n      # Include all files with the .js extension\n      (nix-filter.matchExt \"js\")\n    ];\n\n    # Works like include, but the reverse.\n    exclude = [\n      ./main.js\n    ];\n  };\n}\n```\n\n# Usage\n\nImport this folder. Eg:\n\n```nix\nlet\n  nix-filter = import ./path/to/nix-filter;\nin\n # ...\n```\n\nThe top-level is a functor that takes:\n* `root` of type `path`: pointing to the root of the source to add to the\n    /nix/store.\n* `name` of type `string` (optional): the name of the derivation (defaults to\n    \"source\")\n* `include` of type `list(string|path|matcher)` (optional): a list of patterns to\n    include (defaults to all).\n* `exclude` of type `list(string|path|matcher)` (optional): a list of patterns to\n    exclude (defaults to none).\n\nThe `include` and `exclude` take a matcher, and automatically convert the `string`\nand `path` types to a matcher.\n\nThe matcher is a function that takes a `path` and `type` and returns `true` if\nthe pattern matches.\n\nThe flake usage is like this:\n\n```nix\n{\n  inputs = {\n    nixpkgs.url = \"github:nixos/nixpkgs/nixos-22.11\";\n    nix-filter.url = \"github:numtide/nix-filter\";\n  };\n  outputs = { self, nixpkgs, nix-filter }:\n    let\n      pkgs = nixpkgs.legacyPackages.x86_64-linux;\n      # Avoid calling it nix-filter as it may result in an infinite recursion\n      filter = nix-filter.lib;\n     # ....\n    in\n    {\n      # ...\n    };\n}\n```\n\n## Builtin matchers\n\nThe functor also contains a number of matchers:\n\n* `nix-filter.matchExt`: `ext` -\u003e returns a function that matches the given file extension.\n* `nix-filter.inDirectory`: `directory` -\u003e returns a function that matches a directory and\n    any path inside of it.\n* `nix-filter.isDirectory`: matches all paths that are directories\n\n## Combining matchers\n\n* `and`: `a -\u003e b -\u003e c`\n  combines the result of two matchers into a new matcher.\n* `or_`: `a -\u003e b -\u003e c`\n  combines the result of two matchers into a new matcher.\n\nNOTE: `or` is a keyword in nix, which is why we use a variation here.\n\nREMINDER: both, `include` \u0026 `exlude` already XOR elements, so `or_` is\nnot useful at the top level.\n\n# Design notes\n\nThis solution uses `builtins.path { path, name, filter ? path: type: true }`\nunder the hood, which ships with Nix.\n\nWhile traversing the filesystem, starting from `path`, it will call `filter`\non each file and folder recursively. If the `filter` returns `false` then the\nfile or folder is ignored. If a folder is ignored, it won't recurse into it\nanymore.\n\nBecause of that, it makes it difficult to implement recursive glob matchers.\nSomething like `**/*.js` would necessarily have to add every folder, to be\nable to traverse them. And those empty folders will end-up in the output.\n\nIf we want to control rebuild, it's important to have a fixed set of folders.\n\nOne possibility is to use a two-pass system, where first all the folders are\nbeing added, and then the empty ones are being filtered out. But all of this\nhappens at Nix evaluation time. Nix evaluation is already slow enough like\nthat.\n\nThat's why nix-filter is asking the users to explicitly list all the folders\nthat they want to `include`, and using only an `exclude` is not recommended.\n\n# Future development\n\nAdd more matchers.\n\n# Related projects\n\n* globset - a superior implementation that is compatible with nixpkgs\n    filesets. See https://github.com/pdtpartners/globset\n* nixpkgs' `lib.cleanSourceWith`.\n* All the git-based solutions. See https://github.com/hercules-ci/gitignore.nix#comparison\n\n# License\n\nCopyright (c) 2021 Numtide under the MIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumtide%2Fnix-filter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnumtide%2Fnix-filter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumtide%2Fnix-filter/lists"}