Skip to content

Commit

Permalink
feat: add std.path.filter
Browse files Browse the repository at this point in the history
Easily filter directories based on a simple whitelist of paths:
```
std.path.filter [
  "some/dir"
  "some/other/file"
] ./some/dir
```

`std.set.filter` returns a store path with the filtered directories
contents. This is useful for quickly collecting paths in a large
repository, e.g. a mono-repo.

If the second argument is not a directory, it will simply return a store
path with an empty file (same as passing a constant `false` value to a
`builtins.path` filter.

If a directory is in the list, it's entire contents are added.

This function is used to offer a simple API in the TOML manifest to
include filtered source files as dependencies available at `atom.src`:
```toml
[src]
binSrcA = ["paths" "to" "include"]
binSrcB = ["some" "other" "paths"]
```
  • Loading branch information
nrdxp committed Aug 8, 2024
1 parent 61adaf4 commit a5ed6e0
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
21 changes: 19 additions & 2 deletions src/atom/fromManifest.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ let
file = builtins.readFile path;
config = builtins.fromTOML file;
atom = config.atom or { };
src = config.src or { };
name = atom.name or (mod.errors.missingName path);

features' =
Expand All @@ -25,9 +26,9 @@ let
compose = config.compose or { };

root = atom.path or name;
extern =
fetches =
let
fetcher = nix.fetcher or "native"; # native doesn't exist yet
fetcher = nix.fetcher or "native"; # TODO: native doesn't exist yet
conf = config.fetcher or { };
f = conf.${fetcher} or { };
root = f.root or "npins";
Expand Down Expand Up @@ -55,6 +56,22 @@ let
else
{ };

srcs =
let
filter = scopedImport {
std = builtins // {
string.split = import ../std/string/split.nix;
};
} ../std/path/filter.nix;
in
mod.filterMap (
name: paths: if builtins.isList paths != true then null else filter paths (dirOf path)
) src;

extern = fetches // {
src = srcs;
};

meta = atom.meta or { };

composeFeatures = compose.features or { };
Expand Down
20 changes: 14 additions & 6 deletions src/atom/mod.nix
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,22 @@ rec {
if s == k then null else { ${s} = v; }
);

rmNixSrcs = l.filterSource (
path: type:
rmNixSrcs =
path:
let
file = parse (baseNameOf path);
name = baseNameOf path;
in
(type == "regular" && file.ext or null != "nix")
|| (type == "directory" && !l.pathExists "${path}/mod.nix")
);
l.path {
inherit name path;
filter = (
path: type:
let
file = parse name;
in
(type == "regular" && file.ext or null != "nix")
|| (type == "directory" && !l.pathExists "${path}/mod.nix")
);
};

readStd = opts: fromManifest { inherit (opts) __internal__test features; };

Expand Down
29 changes: 29 additions & 0 deletions src/std/path/filter.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
paths: path:
let
f =
dir:
let
pred = builtins.elem dir paths;
next = f (dirOf dir);
in
dir != "." && (pred || next);

type = builtins.readFileType path;
name =
let
s = std.string.split "-" path;
pred = builtins.match "^${builtins.storeDir}/.*" (toString path) == null;
in
if pred || builtins.length s < 2 then baseNameOf path else builtins.elemAt s 1;
in
builtins.path {
inherit path name;
filter =
p: t:
let
frag = builtins.match "^${toString path}/(.*)" p;
frag' = builtins.head frag;
pred = if frag == null then false else builtins.elem frag' paths;
in
(t == "directory" && type == "directory" && pred) || f (dirOf frag');
}
5 changes: 5 additions & 0 deletions src/std/string/split.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sep: str:
let
p = builtins.split sep (toString str);
in
builtins.filter (x: builtins.typeOf x == "string") p

0 comments on commit a5ed6e0

Please sign in to comment.