Modular, context-aware and aspect-oriented dendritic Nix configurations.
Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/
den.oeiuwq.com
configurations
den
dendritic
nix
aspect
oriented
1{
2 inputs,
3 den,
4 lib,
5 eg,
6 # deadnix: skip
7 __findFile ? __findFile,
8 ...
9}:
10let
11 # module for testing inclusion of namespaces
12 simsModule.nixos.options.sims = lib.mkOption {
13 type = lib.types.listOf lib.types.str;
14 };
15in
16{
17 # enable <angle/bracket> syntax for finding aspects.
18 _module.args.__findFile = den.lib.__findFile;
19
20 imports = [
21 # create a local namespace and output at flake.denful.eg
22 (inputs.den.namespace "eg" true)
23
24 # you can also mount a namespace from many input sources.
25 # the second argument becomes an array of inputs.
26 (
27 let
28 # NOTE: here we simulate inputA and inputB are flakes.
29 inputA.denful.sim.ul._.a._.tion.nixos.sims = [ "inputA simulation" ];
30 inputB.denful.sim.ul._.a._.tion.nixos.sims = [ "inputB simulation" ];
31 exposeToFlake = true;
32 in
33 inputs.den.namespace "sim" [
34 inputA
35 inputB
36 exposeToFlake
37 ]
38 )
39 ];
40
41 # define nested aspects in local namespace
42 eg.foo.provides.bar.provides.baz = {
43 nixos.sims = [ "local namespace" ];
44 };
45
46 # augment aspects on a mounted namespace
47 sim.ul._.a._.tion.nixos.sims = [ "local simulation" ];
48
49 den.aspects.rockhopper.includes = [
50 simsModule
51 <eg/foo/bar/baz>
52 <sim/ul/a/tion>
53 ];
54
55 perSystem =
56 { checkCond, rockhopper, ... }:
57 {
58 checks.namespace-eg-flake-output = checkCond "namespace enabled as flake output" (
59 eg == den.ful.eg && eg == <eg> && eg == inputs.self.denful.eg
60 );
61
62 checks.namespace-eg-provides-accessible = checkCond "exact same value" (
63 eg.foo._.bar._.baz == <eg/foo/bar/baz>
64 && eg.foo._.bar._.baz == inputs.self.denful.eg.foo._.bar._.baz
65 );
66
67 checks.namespace-sim-merged = checkCond "merges from all sources" (
68 let
69 expected = [
70 "inputA simulation"
71 "inputB simulation"
72 "local namespace"
73 "local simulation"
74 ];
75 actual = lib.sort (a: b: a < b) rockhopper.config.sims;
76 in
77 expected == actual
78 );
79
80 };
81}