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

namespace flake output as raw type

+22 -14
+14 -2
modules/aspects.nix
··· 1 1 { config, lib, ... }: 2 + let 3 + inherit (config.den.lib.aspects.types) aspectsType; 4 + denfulType = lib.types.attrsOf aspectsType; 5 + in 2 6 { 3 7 config._module.args.den = config.den; 4 8 options.den.aspects = lib.mkOption { 5 9 description = "Den Aspects"; 6 - type = config.den.lib.aspects.types.aspectsType; 7 - default = { }; 10 + default = { }; # generated from den.{hosts, homes, users} 11 + type = aspectsType; 12 + }; 13 + options.den.ful = lib.mkOption { 14 + default = { }; # namespaces (local or merged from inputs) 15 + type = denfulType; 16 + }; 17 + options.flake.denful = lib.mkOption { 18 + default = { }; # flake output (assigned via den.namespace) 19 + type = lib.types.attrsOf lib.types.raw; 8 20 }; 9 21 }
-4
nix/namespace.nix
··· 14 14 15 15 aliasModule = lib.mkAliasOptionModule [ name ] [ "den" "ful" name ]; 16 16 17 - type = lib.types.attrsOf config.den.lib.aspects.types.providerType; 18 - 19 17 outputModule = 20 18 if isOutput then 21 19 { 22 20 config.flake.denful.${name} = config.den.ful.${name}; 23 - options.flake.denful.${name} = lib.mkOption { type = lib.types.raw; }; 24 21 } 25 22 else 26 23 { }; ··· 32 29 outputModule 33 30 ]; 34 31 config._module.args.${name} = config.den.ful.${name}; 35 - options.den.ful.${name} = lib.mkOption { inherit type; }; 36 32 }
+8 -8
templates/examples/modules/_example/ci/namespace.nix
··· 26 26 ( 27 27 let 28 28 # NOTE: here we simulate inputA and inputB are flakes. 29 - inputA.denful.sim.ul._.a._.tion.nixos.sims = [ "from inputA" ]; 30 - inputB.denful.sim.ul._.a._.tion.nixos.sims = [ "from inputB" ]; 29 + inputA.denful.sim.ul._.a._.tion.nixos.sims = [ "inputA simulation" ]; 30 + inputB.denful.sim.ul._.a._.tion.nixos.sims = [ "inputB simulation" ]; 31 31 exposeToFlake = true; 32 32 in 33 33 inputs.den.namespace "sim" [ ··· 40 40 41 41 # define nested aspects in local namespace 42 42 eg.foo.provides.bar.provides.baz = { 43 - nixos.sims = [ "local <eg/foo/bar/baz>" ]; 43 + nixos.sims = [ "local namespace" ]; 44 44 }; 45 45 46 46 # augment aspects on a mounted namespace 47 - sim.ul._.a._.tion.nixos.sims = [ "augmented <sim/ul/a/tion>" ]; 47 + sim.ul._.a._.tion.nixos.sims = [ "local simulation" ]; 48 48 49 49 den.aspects.rockhopper.includes = [ 50 50 simsModule ··· 67 67 checks.namespace-sim-merged = checkCond "merges from all sources" ( 68 68 let 69 69 expected = [ 70 - "augmented <sim/ul/a/tion>" 71 - "from inputA" 72 - "from inputB" 73 - "local <eg/foo/bar/baz>" 70 + "inputA simulation" 71 + "inputB simulation" 72 + "local namespace" 73 + "local simulation" 74 74 ]; 75 75 actual = lib.sort (a: b: a < b) rockhopper.config.sims; 76 76 in