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
at main 147 lines 3.0 kB view raw
1{ 2 inputs, 3 lib, 4 config, 5 ... 6}: 7let 8 inherit (config) den; 9 10 # "Just Give 'Em One of These" - Moe Szyslak 11 # A __functor that applies context to parametric includes (functions) 12 funk = 13 apply: aspect: 14 aspect 15 // { 16 __functor = self: ctx: { 17 includes = builtins.filter (x: x != { }) ( 18 map (apply ctx) (builtins.filter isFn (self.includes or [ ])) 19 ); 20 }; 21 }; 22 23 isFn = f: (builtins.isFunction f) || (builtins.isAttrs f && f ? __functor); 24 canTake = import ./fn-can-take.nix lib; 25 26 # an aspect producing only owned configs 27 owned = (lib.flip builtins.removeAttrs) [ 28 "includes" 29 "__functor" 30 ]; 31 32 # only static includes from an aspect. 33 statics = 34 aspect: 35 aspect 36 // { 37 __functor = 38 self: 39 { class, aspect-chain }: 40 { 41 includes = map (applyStatics { inherit class aspect-chain; }) (self.includes or [ ]); 42 }; 43 }; 44 45 applyStatics = 46 ctx: f: 47 if !isFn f then 48 f 49 else if isStatic f && isCtxStatic ctx then 50 f ctx 51 else 52 { }; 53 54 isStatic = canTake.atLeast { 55 class = ""; 56 aspect-chain = [ ]; 57 }; 58 isCtxStatic = (lib.flip canTake.exactly) ({ class, aspect-chain }: class aspect-chain); 59 60 take.unused = _unused: used: used; 61 take.exactly = take canTake.exactly; 62 take.atLeast = take canTake.atLeast; 63 take.__functor = 64 _: takes: fn: ctx: 65 if takes ctx fn then fn ctx else { }; 66 67 parametric.atLeast = funk (lib.flip take.atLeast); 68 parametric.exactly = funk (lib.flip take.exactly); 69 parametric.expands = 70 attrs: parametric.withOwn (aspect: ctx: parametric.atLeast aspect (ctx // attrs)); 71 parametric.fixedTo = 72 attrs: aspect: 73 aspect 74 // { 75 __functor = 76 self: 77 { class, aspect-chain }: 78 { 79 includes = [ 80 (owned self) 81 (statics self { inherit class aspect-chain; }) 82 (parametric.atLeast self attrs) 83 ]; 84 }; 85 }; 86 parametric.withOwn = 87 functor: aspect: 88 aspect 89 // { 90 __functor = self: ctx: { 91 includes = 92 if isCtxStatic ctx then 93 [ 94 (owned self) 95 (statics self ctx) 96 ] 97 else 98 [ (functor self ctx) ]; 99 }; 100 }; 101 parametric.__functor = _: parametric.withOwn parametric.atLeast; 102 103 aspects = inputs.flake-aspects.lib lib; 104 105 __findFile = import ./den-brackets.nix { inherit lib config; }; 106 107 nh = import ./nh.nix { 108 inherit 109 lib 110 config 111 den 112 inputs 113 ; 114 }; 115 116 ctxApply = import ./ctx-apply.nix { inherit lib den; }; 117 118 home-env = import ./home-env.nix { inherit lib den inputs; }; 119 120 nixModule = import ./nixModule { 121 inherit 122 lib 123 inputs 124 config 125 den-lib 126 ; 127 }; 128 129 den-lib = { 130 inherit 131 parametric 132 aspects 133 __findFile 134 statics 135 owned 136 isFn 137 canTake 138 take 139 isStatic 140 ctxApply 141 nh 142 home-env 143 nixModule 144 ; 145 }; 146in 147den-lib