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
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(core): support functionArgs in IntoPath (#342)

Adds support for functionArgs inside the IntoPath arg of
den.provides.forward.
Includes tests for both home manager and nixos (might be a bit
overkill?).
Also fixes a typo in the documentation `permanance -> permanence`

**usage example:**
```nix
sysPersist =
{ host }:
{
class,
aspect-chain,
}:
den._.forward {
each = lib.singleton class;
fromClass = _: "sysPersist";
intoClass = _: host.class;
intoPath =
_:
{ config, ... }:
[
"environment"
"persistence"
config.impermanence.persistence-dir
];
fromAspect = _: lib.head aspect-chain;
guard = { options, ... }: options ? environment.persistence;
};
```

---------

Signed-off-by: Gelei <juinen@tuinberg.nl>
Co-authored-by: Victor Borja <vborja@apache.org>

authored by

Gelei
Victor Borja
and committed by
GitHub
8b0bfb37 54c31c14

+136 -6
+2 -2
README.md
··· 416 416 each = lib.singleton true; 417 417 fromClass = _: "persys"; 418 418 intoClass = _: host.class; 419 - intoPath = _: [ "environment" "persistance" "/nix/persist/system" ]; 419 + intoPath = _: [ "environment" "persistence" "/nix/persist/system" ]; 420 420 fromAspect = _: den.aspects.${host.aspect}; 421 - guard = { options, config, ... }: options ? environment.persistance; 421 + guard = { options, config, ... }: options ? environment.persistence; 422 422 }; 423 423 424 424 # enable on all hosts
+9 -4
modules/aspects/provides/forward.nix
··· 51 51 intoClass = fwd.intoClass item; 52 52 intoPath = fwd.intoPath item; 53 53 54 + intoPathArgs = if lib.isFunction intoPath then lib.functionArgs intoPath else { }; 55 + intoPathFn = if lib.isFunction intoPath then intoPath else _: intoPath; 56 + staticIntoPath = if lib.isFunction intoPath then [ ] else intoPath; 57 + 54 58 asp = fwd.fromAspect item; 55 59 sourceModule = den.lib.aspects.resolve fromClass asp; 56 60 ··· 76 80 fromClass 77 81 intoClass 78 82 ] 79 - ++ intoPath 83 + ++ staticIntoPath 80 84 ); 81 85 82 86 guardArgs = if guard == null then { } else lib.functionArgs guard; ··· 99 103 ]) 100 104 ]; 101 105 ${intoClass} = { 102 - __functionArgs = guardArgs; 106 + __functionArgs = guardArgs // intoPathArgs; 103 107 __functor = _: args: { 104 108 options.den.fwd.${adapterKey} = lib.mkOption { 105 109 default = { }; ··· 108 112 modules = adapterMods; 109 113 }; 110 114 }; 111 - config = guardFn args (lib.setAttrByPath intoPath args.config.den.fwd.${adapterKey}); 115 + config = guardFn args (lib.setAttrByPath (intoPathFn args) args.config.den.fwd.${adapterKey}); 112 116 }; 113 117 }; 114 118 }; ··· 161 165 evalImport args; 162 166 }; 163 167 164 - needsAdapter = guard != null || adaptArgs != null || adapterModule != null; 168 + needsAdapter = 169 + guard != null || adaptArgs != null || adapterModule != null || builtins.isFunction intoPath; 165 170 needsTopLevelAdapter = needsAdapter && intoPath == [ ]; 166 171 forwarded = forward intoPath; 167 172
+125
templates/ci/modules/features/dynamic-intopath.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.dynamic-intopath = { 4 + 5 + test-dynamic-intoPath-host-scope = denTest ( 6 + { 7 + den, 8 + lib, 9 + igloo, 10 + ... 11 + }: 12 + let 13 + slotMod = 14 + { lib, ... }: 15 + { 16 + options.my-slot = lib.mkOption { 17 + type = lib.types.str; 18 + default = "slot-a"; 19 + }; 20 + options.my-box = lib.mkOption { 21 + type = lib.types.attrsOf ( 22 + lib.types.submoduleWith { 23 + modules = [ 24 + { 25 + config._module.freeformType = lib.types.lazyAttrsOf lib.types.anything; 26 + } 27 + ]; 28 + } 29 + ); 30 + default = { }; 31 + }; 32 + }; 33 + 34 + forwarded = 35 + { class, aspect-chain }: 36 + den._.forward { 37 + each = lib.singleton class; 38 + fromClass = _: "src"; 39 + intoClass = _: "nixos"; 40 + intoPath = 41 + _: 42 + { config, ... }: 43 + [ 44 + "my-box" 45 + config.my-slot 46 + ]; 47 + fromAspect = _: lib.head aspect-chain; 48 + }; 49 + in 50 + { 51 + den.hosts.x86_64-linux.igloo.users.tux = { }; 52 + den.aspects.igloo = { 53 + includes = [ forwarded ]; 54 + nixos.imports = [ slotMod ]; 55 + nixos.my-slot = "slot-b"; 56 + src.my-data = "hello-from-src"; 57 + }; 58 + 59 + expr = igloo.my-box.slot-b.my-data; 60 + expected = "hello-from-src"; 61 + } 62 + ); 63 + 64 + test-dynamic-intoPath-user-scope = denTest ( 65 + { 66 + den, 67 + lib, 68 + igloo, 69 + ... 70 + }: 71 + let 72 + slotMod = 73 + { lib, ... }: 74 + { 75 + options.my-slot = lib.mkOption { 76 + type = lib.types.str; 77 + default = "slot-a"; 78 + }; 79 + options.my-box = lib.mkOption { 80 + type = lib.types.attrsOf ( 81 + lib.types.submoduleWith { 82 + modules = [ 83 + { 84 + config._module.freeformType = lib.types.lazyAttrsOf lib.types.anything; 85 + } 86 + ]; 87 + } 88 + ); 89 + default = { }; 90 + }; 91 + }; 92 + 93 + forwarded = 94 + { class, aspect-chain }: 95 + den._.forward { 96 + each = lib.singleton class; 97 + fromClass = _: "src"; 98 + intoClass = _: "homeManager"; 99 + intoPath = 100 + _: 101 + { config, ... }: 102 + [ 103 + "my-box" 104 + config.my-slot 105 + ]; 106 + fromAspect = _: lib.head aspect-chain; 107 + }; 108 + in 109 + { 110 + den.hosts.x86_64-linux.igloo.users.tux = { }; 111 + den.aspects.igloo.homeManager.home.stateVersion = "25.11"; 112 + den.aspects.tux = { 113 + includes = [ forwarded ]; 114 + homeManager.imports = [ slotMod ]; 115 + homeManager.my-slot = "slot-b"; 116 + src.my-data = "hello-from-src"; 117 + }; 118 + 119 + expr = igloo.home-manager.users.tux.my-box.slot-b.my-data; 120 + expected = "hello-from-src"; 121 + } 122 + ); 123 + 124 + }; 125 + }