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 den,
3 lib,
4 ...
5}:
6let
7 # a test module to check context was forwarded
8 fwdModule.options.fwd = {
9 a = strOpt;
10 b = strOpt;
11 c = strOpt;
12 d = strOpt;
13 e = strOpt;
14 f = strOpt;
15 # unlike strings, pkgs cannot be duplicated/merged, we use this to
16 # ensure no-dups are created from parametric owned modules.
17 pkg = pkgOpt;
18 pkg2 = pkgOpt;
19 pkg3 = pkgOpt;
20 };
21 strOpt = lib.mkOption { type = lib.types.str; };
22 pkgOpt = lib.mkOption { type = lib.types.package; };
23
24 inherit (den.lib) parametric;
25in
26{
27 den.aspects.rockhopper.includes = [
28 { nixos.imports = [ fwdModule ]; }
29 { homeManager.imports = [ fwdModule ]; }
30 den.aspects.fwd._.first
31 ];
32 den.aspects.rockhopper.nixos.fwd.c = "host owned C";
33 den.aspects.rockhopper.homeManager.fwd.a = "host home-managed A";
34
35 # this aspect will take any context and also forward it
36 # into any includes function that can take same context.
37 den.aspects.fwd._.first = parametric {
38 nixos =
39 { pkgs, ... }:
40 {
41 fwd.a = "First owned A";
42 fwd.pkg = pkgs.hello;
43 };
44 homeManager =
45 { pkgs, ... }:
46 {
47 fwd.pkg = pkgs.vim;
48 };
49 includes = [
50 den.aspects.fwd._.second
51 { nixos.fwd.d = "First static includes D"; }
52 den.aspects.fwd._.never
53 den.aspects.fwd._.fourth
54 ];
55 };
56
57 # Note that second has named arguments, while first does not.
58 # the first aspect forwards whatever context it receives.
59 den.aspects.fwd._.second =
60 { host, ... }:
61 parametric.fixedTo { third = "Impact"; } {
62 includes = [ den.aspects.fwd._.third ];
63 nixos =
64 { pkgs, ... }:
65 {
66 fwd.b = "Second owned B for ${host.name}";
67 fwd.pkg2 = pkgs.bat;
68 };
69 homeManager =
70 { pkgs, ... }:
71 {
72 fwd.pkg2 = pkgs.helix;
73 };
74 };
75
76 den.aspects.fwd._.third =
77 { third, ... }:
78 {
79 nixos.fwd.e = "Third ${third}";
80 };
81
82 den.aspects.fwd._.fourth = parametric.expands { planet = "Earth"; } {
83 includes = [ den.aspects.fwd._.fifth ];
84 nixos =
85 { pkgs, ... }:
86 {
87 fwd.pkg3 = pkgs.emacs-nox;
88 };
89 homeManager =
90 { pkgs, ... }:
91 {
92 fwd.pkg3 = pkgs.emacs-nox;
93 };
94 };
95
96 den.aspects.fwd._.fifth =
97 { host, planet, ... }:
98 {
99 nixos.fwd.f = "Fifth ${planet} ${host.name}";
100 };
101
102 den.aspects.fwd._.never =
103 { never-matches }:
104 {
105 nixos.fwd.a = "Imposibru! should never be included ${never-matches}";
106 };
107
108 perSystem =
109 {
110 checkCond,
111 rockhopper,
112 alice-at-rockhopper,
113 ...
114 }:
115 {
116 checks.parametric-fwd-a = checkCond "fwd-a" (rockhopper.config.fwd.a == "First owned A");
117 checks.parametric-fwd-b = checkCond "fwd-b" (
118 rockhopper.config.fwd.b == "Second owned B for rockhopper"
119 );
120 checks.parametric-fwd-c = checkCond "fwd-c" (rockhopper.config.fwd.c == "host owned C");
121 checks.parametric-fwd-d = checkCond "fwd-d" (rockhopper.config.fwd.d == "First static includes D");
122 checks.parametric-fwd-e = checkCond "fwd-e" (rockhopper.config.fwd.e == "Third Impact");
123 checks.parametric-fwd-f = checkCond "fwd-f" (rockhopper.config.fwd.f == "Fifth Earth rockhopper");
124
125 checks.parametric-fwd-pkg = checkCond "fwd-pkg" (lib.getName rockhopper.config.fwd.pkg == "hello");
126 checks.parametric-fwd-pkg2 = checkCond "fwd-pkg2" (lib.getName rockhopper.config.fwd.pkg2 == "bat");
127 checks.parametric-fwd-pkg3 = checkCond "fwd-pkg3" (
128 lib.getName rockhopper.config.fwd.pkg3 == "emacs-nox"
129 );
130
131 checks.parametric-fwd-hm-a = checkCond "fwd-hm-a" (
132 alice-at-rockhopper.fwd.a == "host home-managed A"
133 );
134 checks.parametric-fwd-hm-pkg = checkCond "fwd-hm-pkg" (
135 lib.getName alice-at-rockhopper.fwd.pkg == "vim"
136 );
137 checks.parametric-fwd-hm-pkg2 = checkCond "fwd-hm-pkg2" (
138 lib.getName alice-at-rockhopper.fwd.pkg2 == "helix"
139 );
140 checks.parametric-fwd-hm-pkg3 = checkCond "fwd-hm-pkg3" (
141 lib.getName alice-at-rockhopper.fwd.pkg3 == "emacs-nox"
142 );
143 };
144
145}