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

Fix dups from parametric owned modules (#100)

Fixes #101

authored by oeiuwq.com and committed by

GitHub f6169af6 2034ed6f

+44 -23
+27 -15
nix/lib.nix
··· 20 20 isFn = f: (builtins.isFunction f) || (f ? __functor); 21 21 canTake = import ./fn-can-take.nix lib; 22 22 23 - empty = { 24 - includes = [ ]; 25 - __functor = 26 - self: 27 - # deadnix: skip 28 - { class, aspect-chain }: 29 - self; 30 - }; 31 - 32 23 # an aspect producing only owned configs 33 - owned = aspect: aspect // empty; 24 + owned = (lib.flip builtins.removeAttrs) [ 25 + "includes" 26 + "__functor" 27 + ]; 34 28 35 29 # only static includes from an aspect. 36 30 statics = ··· 57 51 class = ""; 58 52 aspect-chain = [ ]; 59 53 }; 54 + isCtxStatic = (lib.flip canTake.exactly) ( 55 + # deadnix: skip 56 + { class, aspect-chain }: true 57 + ); 60 58 61 59 take.unused = _unused: used: used; 62 60 take.exactly = take canTake.exactly; ··· 67 65 68 66 parametric.atLeast = funk (lib.flip take.atLeast); 69 67 parametric.exactly = funk (lib.flip take.exactly); 70 - parametric.fixedTo = lib.flip (parametric.withOwn parametric.atLeast); 71 68 parametric.expands = 72 69 attrs: aspect: ctx: 73 70 parametric.fixedTo (ctx // attrs) aspect; 71 + parametric.fixedTo = 72 + ctx: aspect: 73 + { class, aspect-chain }: 74 + { 75 + includes = [ 76 + (parametric.atLeast aspect ctx) 77 + (parametricStatics aspect { inherit class aspect-chain; }) 78 + ]; 79 + }; 74 80 parametric.withOwn = 75 81 functor: aspect: 76 82 aspect ··· 78 84 __functor = self: ctx: { 79 85 includes = [ 80 86 (functor self ctx) 81 - (owned self) 82 - ({ 83 - includes = map (applyStatics ctx) self.includes; 84 - }) 87 + (parametricStatics self ctx) 85 88 ]; 86 89 }; 87 90 }; 88 91 parametric.__functor = _: parametric.withOwn parametric.atLeast; 92 + 93 + parametricStatics = self: ctx: { 94 + includes = lib.optionals (isCtxStatic ctx) [ 95 + (owned self) 96 + { 97 + includes = map (applyStatics ctx) self.includes; 98 + } 99 + ]; 100 + }; 89 101 90 102 aspects = inputs.flake-aspects.lib lib; 91 103
+17 -8
templates/examples/modules/_example/ci/parametric-with-owned.nix
··· 8 8 d = strOpt; 9 9 e = strOpt; 10 10 f = strOpt; 11 + # unlike strings, pkgs cannot be duplicated, we use this to 12 + # ensure no-dups are created from parametric owned modules. 13 + pkg = lib.mkOption { type = lib.types.package; }; 11 14 }; 12 15 strOpt = lib.mkOption { type = lib.types.str; }; 13 16 ··· 24 27 # this aspect will take any context and also forward it 25 28 # into any includes function that can take same context. 26 29 den.aspects.fwd._.first = parametric { 27 - nixos.fwd.a = "First owned A"; 30 + nixos = 31 + { pkgs, ... }: 32 + { 33 + fwd.a = "First owned A"; 34 + fwd.pkg = pkgs.hello; 35 + }; 28 36 includes = [ 29 37 den.aspects.fwd._.second 30 38 { nixos.fwd.d = "First static includes D"; } ··· 67 75 perSystem = 68 76 { checkCond, rockhopper, ... }: 69 77 { 70 - checks.parametric-fwd = checkCond "forwarding ctx with owned" ( 71 - rockhopper.config.fwd.a == "First owned A" 72 - && rockhopper.config.fwd.b == "Second owned B for rockhopper" 73 - && rockhopper.config.fwd.c == "host owned C" 74 - && rockhopper.config.fwd.d == "First static includes D" 75 - && rockhopper.config.fwd.e == "Third Impact" 76 - && rockhopper.config.fwd.f == "Fifth Earth rockhopper" 78 + checks.parametric-fwd-a = checkCond "fwd-a" (rockhopper.config.fwd.a == "First owned A"); 79 + checks.parametric-fwd-b = checkCond "fwd-b" ( 80 + rockhopper.config.fwd.b == "Second owned B for rockhopper" 77 81 ); 82 + checks.parametric-fwd-c = checkCond "fwd-c" (rockhopper.config.fwd.c == "host owned C"); 83 + checks.parametric-fwd-d = checkCond "fwd-d" (rockhopper.config.fwd.d == "First static includes D"); 84 + checks.parametric-fwd-e = checkCond "fwd-e" (rockhopper.config.fwd.e == "Third Impact"); 85 + checks.parametric-fwd-f = checkCond "fwd-f" (rockhopper.config.fwd.f == "Fifth Earth rockhopper"); 86 + checks.parametric-fwd-pkg = checkCond "fwd-pkg" (lib.getName rockhopper.config.fwd.pkg == "hello"); 78 87 }; 79 88 80 89 }