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

Test top-level contextual aspects. (#93)

See https://github.com/vic/den/discussions/91 for context.

See
[failure](https://github.com/vic/bugs-den/actions/runs/19377336327/job/55448108522)
for
[reproduction](https://github.com/vic/bugs-den/commit/f81dca61403c7a08e5381b61bcb2fedc1994efb4)

Support for top-level contextual aspects was added at
https://github.com/vic/flake-aspects/pull/14.

Closes #92.

authored by oeiuwq.com and committed by

GitHub 227451c9 5b49190b

+86 -18
+3 -3
templates/bogus/flake.lock
··· 18 18 }, 19 19 "flake-aspects": { 20 20 "locked": { 21 - "lastModified": 1762465224, 22 - "narHash": "sha256-jfXLTwngKXwFOCVfCupHGcCw/OIpgy5lMYIF8KPfMN8=", 21 + "lastModified": 1763284357, 22 + "narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=", 23 23 "owner": "vic", 24 24 "repo": "flake-aspects", 25 - "rev": "4cbae79bc642311f45c211f9c20d20226544b6f9", 25 + "rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49", 26 26 "type": "github" 27 27 }, 28 28 "original": {
+3 -3
templates/default/flake.lock
··· 37 37 }, 38 38 "flake-aspects": { 39 39 "locked": { 40 - "lastModified": 1762465224, 41 - "narHash": "sha256-jfXLTwngKXwFOCVfCupHGcCw/OIpgy5lMYIF8KPfMN8=", 40 + "lastModified": 1763284357, 41 + "narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=", 42 42 "owner": "vic", 43 43 "repo": "flake-aspects", 44 - "rev": "4cbae79bc642311f45c211f9c20d20226544b6f9", 44 + "rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49", 45 45 "type": "github" 46 46 }, 47 47 "original": {
+30 -9
templates/default/modules/aspects/alice.nix
··· 1 - { den, ... }: 1 + { den, eg, ... }: 2 2 { 3 3 den.aspects.alice = { 4 - # You can include other aspects, in this case some 5 - # den included batteries that provide common configs. 4 + 5 + # Alice can include other aspects. 6 + # For small, private one-shot aspects, use let-bindings like here. 7 + # for more complex or re-usable ones, define on their own modules, 8 + # as part of any aspect-subtree. 6 9 includes = 7 10 let 8 - # deadnix: skip # demo: enable <> on lexical scope 11 + # deadnix: skip # not required, showcasing angle-brackets syntax. 9 12 inherit (den.lib) __findFile; 10 13 11 14 customEmacs.homeManager = ··· 16 19 }; 17 20 in 18 21 [ 22 + # from local bindings. 19 23 customEmacs 20 - <eg/autologin> 24 + # from the aspect tree, cooper example is defined bellow 25 + den.aspects.cooper 26 + den.aspects.setHost 27 + # from the `eg` namespace. 28 + eg.autologin 29 + # den included batteries that provide common configs. 21 30 <den/primary-user> # alice is admin always. 22 31 (<den/user-shell> "fish") # default user shell 23 32 ]; ··· 26 35 nixos = 27 36 { pkgs, ... }: 28 37 { 29 - users.users.alice = { 30 - description = "Alice Cooper"; 31 - packages = [ pkgs.vim ]; 32 - }; 38 + users.users.alice.packages = [ pkgs.vim ]; 33 39 }; 34 40 35 41 # Alice home-manager. ··· 46 52 nixos.programs.nh.enable = host.name == "igloo"; 47 53 }; 48 54 }; 55 + 56 + # This is a context-aware aspect, that emits configurations 57 + # **anytime** at least the `user` data is in context. 58 + # read more at https://vic.github.io/den/context-aware.html 59 + den.aspects.cooper = 60 + { user, ... }: 61 + { 62 + nixos.users.users.${user.userName}.description = "Alice Cooper"; 63 + }; 64 + 65 + den.aspects.setHost = 66 + { host, ... }: 67 + { 68 + networking.hostName = host.hostName; 69 + }; 49 70 }
+3 -3
templates/examples/flake.lock
··· 37 37 }, 38 38 "flake-aspects": { 39 39 "locked": { 40 - "lastModified": 1762148645, 41 - "narHash": "sha256-NfxjuuA1p7Sn+OX0HD+p6LepxRFYmahaybvN7+D3GZQ=", 40 + "lastModified": 1763284357, 41 + "narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=", 42 42 "owner": "vic", 43 43 "repo": "flake-aspects", 44 - "rev": "895538b1372ecbe4966db85553b11eb64a72086c", 44 + "rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49", 45 45 "type": "github" 46 46 }, 47 47 "original": {
+47
templates/examples/modules/_example/ci/top-level-parametric.nix
··· 1 + # it is possible for top-level aspects directly under 2 + # den.aspects to take a context argument. 3 + { den, lib, ... }: 4 + let 5 + # A module to test that toplevel had context. 6 + topLevel = name: { 7 + config.tops = name; 8 + options.tops = lib.mkOption { type = lib.types.str; }; 9 + }; 10 + in 11 + { 12 + 13 + den.aspects.toplevel-user = 14 + { user, ... }: 15 + { 16 + nixos.imports = [ (topLevel user.name) ]; 17 + }; 18 + 19 + den.aspects.toplevel-host = 20 + { host, ... }: 21 + { 22 + homeManager.imports = [ (topLevel host.name) ]; 23 + }; 24 + 25 + den.aspects.alice.includes = [ 26 + den.aspects.toplevel-host 27 + den.aspects.toplevel-user 28 + ]; 29 + 30 + perSystem = 31 + { 32 + checkCond, 33 + alice-at-rockhopper, 34 + rockhopper, 35 + ... 36 + }: 37 + { 38 + checks.alice-toplevel-user = checkCond "alice toplevel param aspect" ( 39 + rockhopper.config.tops == "alice" 40 + ); 41 + 42 + checks.alice-toplevel-host = checkCond "alice toplevel param aspect" ( 43 + alice-at-rockhopper.tops == "rockhopper" 44 + ); 45 + }; 46 + 47 + }