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.

Fix double inclusion of host owned settings. (#65)

Fixes #64

authored by

Victor Borja and committed by
GitHub
316f5596 8843a561

+73 -47
+45 -27
modules/aspects/dependencies.nix
··· 8 8 owned 9 9 statics 10 10 parametric 11 - take 12 11 ; 12 + 13 + inherit (den.lib.take) exactly; 13 14 14 15 dependencies = [ 15 - ({ home, ... }: baseDeps home) 16 - ({ host, ... }: baseDeps host) 17 - ({ user, ... }: baseDeps user) 18 - (os osIncludesFromUsers) 19 - (hm hmIncludesFromHost) 16 + (exactly ({ home }: baseDeps home)) 17 + (exactly ({ host }: baseDeps host)) 18 + (exactly ({ user }: baseDeps user)) 19 + (exactly osDependencies) 20 + (exactly hmDependencies) 20 21 ]; 21 - 22 - # deadnix: skip # exact { OS } to avoid recursion 23 - os = fn: { OS, ... }@ctx: take.exactly ctx fn; 24 - # deadnix: skip # exact { HM } to avoid recursion 25 - hm = fn: { HM, ... }@ctx: take.exactly ctx fn; 26 22 27 23 baseDeps = 28 24 from: ··· 39 35 ]; 40 36 }; 41 37 42 - osIncludesFromUsers = 38 + from = o: (lib.flip parametric) den.aspects.${o.aspect}; 39 + 40 + osDependencies = 43 41 { OS }: 44 42 let 45 43 inherit (OS) host; 46 44 users = builtins.attrValues host.users; 47 - userDeps = user: parametric { inherit OS user host; } den.aspects.${user.aspect}; 48 - userContribs.includes = map userDeps users; 49 - hostDeps = user: parametric { inherit user host; } den.aspects.${host.aspect}; 50 - hostContribs.includes = map hostDeps users; 45 + hostIncludes = [ 46 + (from host { inherit host; }) 47 + (from host { 48 + inherit OS host; 49 + fromHost = host; 50 + }) 51 + ]; 52 + userIncludes = user: [ 53 + (from user { inherit user; }) 54 + (from user { 55 + inherit OS user host; 56 + fromUser = user; 57 + }) 58 + (from host { 59 + inherit OS user host; 60 + fromHost = host; 61 + }) 62 + ]; 51 63 in 52 64 { 53 - includes = [ 54 - hostContribs 55 - userContribs 56 - ]; 65 + includes = hostIncludes ++ (map (u: { includes = userIncludes u; }) users); 57 66 }; 58 67 59 - hmIncludesFromHost = 68 + hmDependencies = 60 69 { HM }: 61 70 let 62 71 inherit (HM) user host; 63 - userDeps = parametric { inherit HM user host; } den.aspects.${user.aspect}; 64 - hostDeps = parametric { inherit HM user host; } den.aspects.${host.aspect}; 72 + hostIncludes = [ 73 + (from host { inherit host; }) 74 + (from host { 75 + inherit HM user host; 76 + fromHost = host; 77 + }) 78 + ]; 79 + userIncludes = [ 80 + (from user { inherit user; }) 81 + (from user { 82 + inherit HM user host; 83 + fromUser = user; 84 + }) 85 + ]; 65 86 in 66 87 { 67 - includes = [ 68 - userDeps 69 - hostDeps 70 - ]; 88 + includes = hostIncludes ++ userIncludes; 71 89 }; 72 90 in 73 91 {
+4 -2
modules/aspects/provides/user-shell.nix
··· 28 28 inherit nixos darwin homeManager; 29 29 }; 30 30 31 + inherit (den.lib.take) exactly; 32 + 31 33 in 32 34 { 33 35 den.provides.user-shell = shell: { 34 36 inherit description; 35 37 __functor = den.lib.parametric true; 36 38 includes = [ 37 - ({ user, ... }: userShell shell user) 38 - ({ home, ... }: userShell shell home) 39 + (exactly ({ user }: userShell shell user)) 40 + (exactly ({ home }: userShell shell home)) 39 41 ]; 40 42 }; 41 43 }
+4 -4
nix/lib.nix
··· 63 63 take.exactly = take canTake.exactly; 64 64 take.atLeast = take canTake.atLeast; 65 65 take.__functor = 66 - _: takes: ctx: fn: 66 + _: takes: fn: ctx: 67 67 if takes ctx fn then fn ctx else { }; 68 68 69 - parametric.atLeast = funk take.atLeast; 70 - parametric.exactly = funk take.exactly; 69 + parametric.atLeast = funk (lib.flip take.atLeast); 70 + parametric.exactly = funk (lib.flip take.exactly); 71 71 parametric.context = lib.flip parametric.atLeast; 72 - parametric.expands = attrs: funk (ctx: take.atLeast (attrs // ctx)); 72 + parametric.expands = attrs: funk (ctx: (lib.flip take.atLeast) (attrs // ctx)); 73 73 parametric.__functor = 74 74 self: ctx: 75 75 if ctx == true then
+2 -5
templates/bogus/modules/bug.nix
··· 18 18 expr.len = lib.length tux.packages; 19 19 expr.names = map lib.getName tux.packages; 20 20 21 - expected.len = 2; 22 - expected.names = [ 23 - "hello" 24 - "hello" 25 - ]; 21 + expected.len = 1; 22 + expected.names = [ "hello" ]; 26 23 in 27 24 { 28 25 inherit expr expected;
+12 -5
templates/default/modules/_example/aspects.nix
··· 14 14 ... 15 15 }: 16 16 let 17 + # A custom `nixos` class module that defines an option `names`. 18 + # Used to test that we are not duplicating values from owned configs. 19 + nixosNames.options.names = lib.mkOption { type = lib.types.listOf lib.types.str; }; 17 20 18 21 # Example: A static aspect for vm installers. 19 22 vm-bootable = { ··· 42 45 { }; 43 46 44 47 # Example: adds hello into each user. provides only to OS. 45 - one-hello-package-for-each-user = 48 + hello-package-for-user = 46 49 { 47 50 OS, 51 + fromUser, 48 52 user, 49 53 host, 50 54 ... 51 55 }: 52 - den.lib.take.unused [ OS ] { 56 + den.lib.take.unused [ OS fromUser ] { 53 57 ${host.class} = 54 58 { pkgs, ... }: 55 59 { ··· 95 99 # Example: parametric { host } aspect 96 100 set-host-name 97 101 98 - # Example: parametric { fromUser, toHost } aspect. 99 - one-hello-package-for-each-user 102 + # Example: parametric { OS, fromUser } aspect. 103 + hello-package-for-user 100 104 101 105 # Example: parametric over many contexts: { home }, { host, user }, { fromUser, toHost } 102 106 den.provides.define-user ··· 128 132 den._.primary-user 129 133 ]; 130 134 131 - # Example: host provides parametric user configuration. 135 + den.aspects.rockhopper.nixos.names = [ "tux" ]; 132 136 den.aspects.rockhopper.includes = [ 137 + # Example: importing a third-party nixos module. 138 + { nixos.imports = [ nixosNames ]; } 139 + # Example: host provides parametric user configuration. 133 140 host-to-user-conditional 134 141 ]; 135 142
+6 -4
templates/default/modules/_example/ci.nix
··· 95 95 alice-hello-enabled-by-default = checkCond "added hello at user packages" ( 96 96 let 97 97 progs = rockhopper.config.users.users.alice.packages; 98 - expr.len = lib.length progs; 99 - expr.name = lib.getName (lib.head progs); 100 - expected.len = 1; 101 - expected.name = "hello"; 98 + expr = map lib.getName progs; 99 + expected = [ "hello" ]; 102 100 in 103 101 expr == expected 102 + ); 103 + 104 + rockhopper-names-single-entry = checkCond "custom nixos array option set once" ( 105 + rockhopper.config.names == [ "tux" ] 104 106 ); 105 107 106 108 };