Skip to content

Commit 21c639d

Browse files
vicCopilot
andauthored
feat: initFilter allows looking other file types, ignore other than /_. (#19)
* feat: initFilter allows looking other file types, ignore other than /_. * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 234b5bb commit 21c639d

File tree

3 files changed

+83
-12
lines changed

3 files changed

+83
-12
lines changed

README.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
> Helper functions for import of [Nixpkgs module system](https://nix.dev/tutorials/module-system/) modules under a directory recursively
44
5-
Module class agnostic; can be used for NixOS, nix-darwin, home-manager, flake-parts, NixVim.
5+
- Flake callable; Easy to use, intuitive for the most common use case: `inputs.import-tree ./modules`
6+
- Module class agnostic; can be used for NixOS, nix-darwin, home-manager, flake-parts, NixVim.
7+
- Can be used outside flakes as a dependencies-free lib; Just import our `./default.nix`.
8+
- Can be used to list other file types, not just `.nix`. See `.initFilter`, `.files` API.
9+
- Extensible API. import-tree objects are customizable. See `.addAPI`.
610

711
## Quick Usage (with flake-parts)
812

@@ -29,7 +33,9 @@ you can use the import-tree API (read below for more).
2933

3034
## Ignored files
3135

32-
Paths that have a component that begins with an underscore are ignored.
36+
By default, paths having a component that begins with an underscore (`/_`) are ignored.
37+
38+
This can be changed by using `.initFilter` API.
3339

3440
<details>
3541
<summary>
@@ -177,6 +183,8 @@ Or, in a simpler but less readable way:
177183
(import-tree.filter (lib.hasInfix ".mod.")).filter (lib.hasSuffix "default.nix") ./some-dir
178184
```
179185

186+
See also `import-tree.initFilter`.
187+
180188
### `import-tree.match` and `import-tree.matchNot`
181189

182190
`match` takes a regular expression. The regex should match the full path for the path to be selected. Matching is done with `builtins.match`.
@@ -297,6 +305,37 @@ import-tree.leafs
297305
Returns a fresh import-tree with empty state. If you previously had any path, lib, filter, etc,
298306
you might need to set them on the new empty tree.
299307

308+
### `import-tree.initFilter`
309+
310+
*Replaces* the initial filter which defaults to: Include files with `.nix` suffix and not having `/_` infix.
311+
312+
_NOTE_: initFilter is non-accumulating and is the *first* filter to run before those accumulated via `filter`/`match`.
313+
314+
You can use this to make import-tree scan for other file types or change the ignore convention.
315+
316+
```nix
317+
# import-tree.initFilter : (path -> bool) -> import-tree
318+
319+
import-tree.initFilter (p: lib.hasSuffix ".nix" p && !lib.hasInfix "/ignored/") # nix files not inside /ignored/
320+
import-tree.initFilter (lib.hasSuffix ".md") # scan for .md files everywhere, nothing ignored.
321+
```
322+
323+
### `import-tree.files`
324+
325+
A shorthand for `import-tree.leafs.result`. Returns a list of matching files.
326+
327+
This can be used when you don't want to import the tree, but just get a list of files from it.
328+
329+
Useful for listing files other than `.nix`, for example, for passing all `.js` files to a minifier:
330+
331+
_TIP_: remember to use `withLib` when *not* using import-tree as a module import.
332+
333+
```nix
334+
# import-tree.files : [ <list-of-files> ]
335+
336+
((import-tree.withLib lib).initFilter (lib.hasSuffix ".js")).files # => list of all .js files
337+
```
338+
300339
### `import-tree.result`
301340

302341
Exactly the same as calling the import-tree object with an empty list `[ ]`.

checkmate.nix

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ in
9292
};
9393

9494
addPath."test `addPath` prepends a path to filter" = {
95-
expr = (lit.addPath ./tree/x).leafs.result;
95+
expr = (lit.addPath ./tree/x).files;
9696
expected = [ ./tree/x/y.nix ];
9797
};
9898

9999
addPath."test `addPath` can be called multiple times" = {
100-
expr = ((lit.addPath ./tree/x).addPath ./tree/a/b).leafs.result;
100+
expr = ((lit.addPath ./tree/x).addPath ./tree/a/b).files;
101101
expected = [
102102
./tree/x/y.nix
103103
./tree/a/b/b_a.nix
@@ -106,31 +106,56 @@ in
106106
};
107107

108108
addPath."test `addPath` identity" = {
109-
expr = ((lit.addPath ./tree/x).addPath ./tree/a/b).leafs.result;
109+
expr = ((lit.addPath ./tree/x).addPath ./tree/a/b).files;
110110
expected = lit.leafs [
111111
./tree/x
112112
./tree/a/b
113113
];
114114
};
115115

116-
reset."test `new` returns a clear state" = {
116+
new."test `new` returns a clear state" = {
117117
expr = lib.pipe lit [
118118
(i: i.addPath ./tree/x)
119119
(i: i.addPath ./tree/a/b)
120120
(i: i.new)
121121
(i: i.addPath ./tree/modules/hello-world)
122122
(i: i.withLib lib)
123-
(i: i.leafs.result)
123+
(i: i.files)
124124
];
125125
expected = [ ./tree/modules/hello-world/mod.nix ];
126126
};
127127

128+
initFilter."test can change the initial filter to look for other file types" = {
129+
expr = (lit.initFilter (p: lib.hasSuffix ".txt" p)).leafs [ ./tree/a ];
130+
expected = [ ./tree/a/a.txt ];
131+
};
132+
133+
initFilter."test initf does filter non-paths" = {
134+
expr =
135+
let
136+
mod = (it.initFilter (x: !(x ? config.boom))) [
137+
{
138+
options.hello = lib.mkOption {
139+
default = "world";
140+
type = lib.types.str;
141+
};
142+
}
143+
{
144+
config.boom = "boom";
145+
}
146+
];
147+
res = lib.modules.evalModules { modules = [ mod ]; };
148+
in
149+
res.config.hello;
150+
expected = "world";
151+
};
152+
128153
addAPI."test extends the API available on an import-tree object" = {
129154
expr =
130155
let
131156
extended = lit.addAPI { helloOption = self: self.addPath ./tree/modules/hello-option; };
132157
in
133-
extended.helloOption.leafs.result;
158+
extended.helloOption.files;
134159
expected = [ ./tree/modules/hello-option/mod.nix ];
135160
};
136161

@@ -139,7 +164,7 @@ in
139164
let
140165
first = lit.addAPI { helloOption = self: self.addPath ./tree/modules/hello-option; };
141166
second = first.addAPI { helloWorld = self: self.addPath ./tree/modules/hello-world; };
142-
extended = second.addAPI { res = self: self.helloOption.leafs.result; };
167+
extended = second.addAPI { res = self: self.helloOption.files; };
143168
in
144169
extended.res;
145170
expected = [ ./tree/modules/hello-option/mod.nix ];

default.nix

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ let
33
{
44
lib ? null,
55
pipef ? null,
6+
initf ? null,
67
filterf,
78
mapf,
89
paths,
@@ -28,7 +29,7 @@ let
2829
leafs =
2930
lib: root:
3031
let
31-
initialFilter = andNot (lib.hasInfix "/_") (lib.hasSuffix ".nix");
32+
treeFiles = t: (t.withLib lib).files;
3233
listFilesRecursive =
3334
x:
3435
if isImportTree x then
@@ -39,9 +40,11 @@ let
3940
lib.filesystem.listFilesRecursive x
4041
else
4142
[ x ];
42-
treeFiles = t: (t.withLib lib).leafs.result;
43+
nixFilter = andNot (lib.hasInfix "/_") (lib.hasSuffix ".nix");
44+
initialFilter = if initf != null then initf else nixFilter;
4345
pathFilter = compose (and filterf initialFilter) toString;
44-
filter = x: if isPathLike x then pathFilter x else filterf x;
46+
otherFilter = and filterf (if initf != null then initf else (_: true));
47+
filter = x: if isPathLike x then pathFilter x else otherFilter x;
4548
in
4649
lib.pipe
4750
[ paths root ]
@@ -118,12 +121,16 @@ let
118121

119122
# Configuration updates (non-accumulating)
120123
withLib = lib: mergeAttrs { inherit lib; };
124+
initFilter = initf: mergeAttrs { inherit initf; };
121125
pipeTo = pipef: mergeAttrs { inherit pipef; };
122126
leafs = mergeAttrs { pipef = (i: i); };
123127

124128
# Applies empty (for already path-configured trees)
125129
result = (self f) [ ];
126130

131+
# Return a list of all filtered files.
132+
files = (self f).leafs.result;
133+
127134
# returns the original empty state
128135
new = callable;
129136
};

0 commit comments

Comments
 (0)