Cross-Aspect Dependencies
includes
Section titled “includes”Every aspect can declare an includes list — references to other aspects (or providers) that should be resolved together:
flake.aspects = { aspects, ... }: { server = { includes = with aspects; [ networking monitoring ]; nixos = { services.nginx.enable = true; }; }; networking.nixos = { networking.firewall.enable = true; }; monitoring.nixos = { services.prometheus.enable = true; };};When server is resolved for class "nixos", the result is:
{ imports = [ { services.nginx.enable = true; } # server.nixos { networking.firewall.enable = true; } # networking.nixos { services.prometheus.enable = true; } # monitoring.nixos ];}Only classes present on the included aspect propagate. If networking has no darwin key, nothing from networking appears when resolving for "darwin".
Transitive resolution
Section titled “Transitive resolution”Dependencies resolve transitively. If A includes B and B includes C, resolving A collects configs from A, B, and C:
flake.aspects = { aspects, ... }: { one = { includes = [ aspects.two ]; classOne.bar = [ "1" ]; }; two = { includes = [ aspects.two._.three-and-four ]; classOne.bar = [ "2" ]; provides = { aspects, ... }: { three-and-four = { classOne.bar = [ "3" ]; includes = [ aspects.four ]; }; four.classOne.bar = [ "4" ]; }; };};Resolving one for classOne collects ["1", "2", "3", "4"].
Inline aspects as includes
Section titled “Inline aspects as includes”includes entries don’t have to be references to named aspects. They can be inline aspect attrsets:
server.includes = [ { nixos = { services.sshd.enable = true; }; }];Or context-aware providers:
server.includes = [ ({ class, aspect-chain }: { ${class}.tag = "included-by-${(lib.last aspect-chain).name}"; })];