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

Add more tests

+36 -10
+10 -8
nix/lib.nix
··· 67 67 68 68 parametric.atLeast = funk (lib.flip take.atLeast); 69 69 parametric.exactly = funk (lib.flip take.exactly); 70 - parametric.fixedTo = lib.flip parametric.atLeast; 71 - parametric.expands = attrs: funk (ctx: (lib.flip take.atLeast) (ctx // attrs)); 70 + parametric.fixedTo = lib.flip (parametric.withOwn parametric.atLeast); 71 + parametric.expands = 72 + attrs: aspect: ctx: 73 + parametric.fixedTo (ctx // attrs) aspect; 72 74 parametric.withOwn = 73 - aspect: 75 + functor: aspect: 74 76 aspect 75 77 // { 76 78 __functor = self: ctx: { 77 79 includes = [ 78 - (parametric.atLeast self ctx) 80 + (functor self ctx) 79 81 (owned self) 80 82 ({ 81 83 includes = map (applyStatics ctx) self.includes; ··· 84 86 }; 85 87 }; 86 88 parametric.__functor = 87 - self: arg: 89 + _: arg: 88 90 if arg == true then 89 - self.atLeast 91 + parametric.atLeast 90 92 else if arg == false then 91 - self.exactly 93 + parametric.exactly 92 94 else if builtins.isAttrs arg then 93 - self.withOwn arg 95 + parametric.withOwn parametric.atLeast arg 94 96 else 95 97 funk arg; 96 98
+26 -2
templates/examples/modules/_example/ci/parametric-with-owned.nix
··· 6 6 b = strOpt; 7 7 c = strOpt; 8 8 d = strOpt; 9 + e = strOpt; 10 + f = strOpt; 9 11 }; 10 12 strOpt = lib.mkOption { type = lib.types.str; }; 13 + 14 + inherit (den.lib) parametric; 11 15 in 12 16 { 13 17 ··· 21 25 # its owned configs and static (non-functional) includes. 22 26 # Usage: just call `parametric` with an aspect. 23 27 # or alternatively, set `__functor = den.lib.parametric;` 24 - den.aspects.fwd._.first = den.lib.parametric { 28 + den.aspects.fwd._.first = parametric { 25 29 nixos.fwd.a = "First owned A"; 26 30 includes = [ 27 31 den.aspects.fwd._.second 28 32 { nixos.fwd.d = "First static includes D"; } 29 33 den.aspects.fwd._.never 34 + den.aspects.fwd._.fourth 30 35 ]; 31 36 }; 32 37 ··· 34 39 # the first aspect forwards whatever context it receives. 35 40 den.aspects.fwd._.second = 36 41 { host, ... }: 37 - { 42 + parametric.fixedTo { third = "Impact"; } { 38 43 nixos.fwd.b = "Second owned B for ${host.name}"; 44 + includes = [ den.aspects.fwd._.third ]; 45 + }; 46 + 47 + den.aspects.fwd._.third = 48 + { third, ... }: 49 + { 50 + nixos.fwd.e = "Third ${third}"; 51 + }; 52 + 53 + den.aspects.fwd._.fourth = parametric.expands { planet = "Earth"; } { 54 + includes = [ den.aspects.fwd._.fifth ]; 55 + }; 56 + 57 + den.aspects.fwd._.fifth = 58 + { host, planet, ... }: 59 + { 60 + nixos.fwd.f = "Fifth ${planet} ${host.name}"; 39 61 }; 40 62 41 63 den.aspects.fwd._.never = ··· 52 74 && rockhopper.config.fwd.b == "Second owned B for rockhopper" 53 75 && rockhopper.config.fwd.c == "host owned C" 54 76 && rockhopper.config.fwd.d == "First static includes D" 77 + && rockhopper.config.fwd.e == "Third Impact" 78 + && rockhopper.config.fwd.f == "Fifth Earth rockhopper" 55 79 ); 56 80 }; 57 81