Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,18 @@ Paths that have a component that begins with an underscore are ignored.

## API usage

The following goes recursively through the provided `./modules` path and imports the files whose names end with `.nix`.
The following goes recursively through `./modules` and imports all `.nix` files.

```nix
{config, ...} {
imports = [ (import-tree ./modules) ];
}
```

For more advanced usage, `import-tree` can be configured via its builder API.
This means that the result of calling a function on an `import-tree` object
is itself another `import-tree` object.

</summary>

## Obtaining the API
Expand Down Expand Up @@ -89,16 +93,34 @@ The following is valid usage:
}
```

As an special case, when the single argument given to an `import-tree` object is an
attribute-set *meaning it is _NOT_ a path or list of paths*, the `import-tree` object
assumes it is being imported as a module. This way, a pre-configured `import-tree` can
also be used directly in a list of module imports.

This is useful for authors exposing pre-configured `import-tree`s that users can directly
add to their import list or continue configuring themselves using the API.

```nix
let
# imagine this configured tree is actually provided by some flake or library.
# users can directly import it or continue using API methods on it.
configured-tree = import-tree.addPath [./a [./b]]; # paths are configured by library author.
in {
imports = [ configured-tree ]; # but then imported or further configured by the library user.
}
```

## Configurable behavior

`import-tree` functions with custom behavior can be obtained using a builder pattern.
`import-tree` objects with custom behavior can be obtained using a builder pattern.
For example:

```nix
lib.pipe import-tree [
(i: i.mapWith lib.traceVal) # trace all paths
(i: i.mapWith lib.traceVal) # trace all paths. useful for debugging what is being imported.
(i: i.filtered (lib.hasInfix ".mod.")) # filter nix files by some predicate
(i: i ./modules) # finally, call the configured callable with a path
(i: i ./modules) # finally, call the configured import-tree with a path
]
```

Expand Down
18 changes: 18 additions & 0 deletions checkmate.nix
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ in
oneElement inner.imports;
expected = ./tree/x/y.nix;
};

import-tree."test evaluates returned module as part of module-eval" = {
expr =
let
res = lib.modules.evalModules { modules = [ (it ./tree/modules) ]; };
in
res.config.hello;
expected = "world";
};

import-tree."test can itself be used as a module" = {
expr =
let
res = lib.modules.evalModules { modules = [ (it.addPath ./tree/modules) ]; };
in
res.config.hello;
expected = "world";
};
};

}
Expand Down
17 changes: 13 additions & 4 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,27 @@ let
attrs: k: f:
attrs // { ${k} = f attrs.${k}; };

functor = self: perform self.config;
functor =
self: args:
let
imported-as-module = builtins.isAttrs args;
module = {
imports = [ (perform self.__config [ ]) ];
};
result = perform self.__config args;
in
if imported-as-module then module else result;

callable =
let
config = {
__config = {
# Accumulated configuration
mapf = (i: i);
filterf = _: true;
paths = [ ];

__functor = self: f: {
config = (f self);
__config = (f self);
__functor = functor;

# Configuration updates (accumulating)
Expand All @@ -88,7 +97,7 @@ let
};
};
in
config (c: c);
__config (c: c);

in
callable
7 changes: 7 additions & 0 deletions tree/modules/hello-option/mod.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{ lib, ... }:
{
options.hello = lib.mkOption {
type = lib.types.str;
default = "goodbye";
};
}
3 changes: 3 additions & 0 deletions tree/modules/hello-world/mod.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
hello = "world";
}