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(batteries): remove bidirectional (#308)

authored by

Victor Borja and committed by
GitHub
54ad0927 35542c55

+233 -445
+1 -1
docs/astro.config.mjs
··· 70 70 { label: 'From Flake to Den', slug: 'guides/from-flake-to-den' }, 71 71 { label: 'Declare Hosts & Users', slug: 'guides/declare-hosts' }, 72 72 { label: 'Configure Aspects', slug: 'guides/configure-aspects' }, 73 - { label: 'Host<->User Mutual Config', slug: 'guides/bidirectional' }, 73 + { label: 'Host<->User Mutual Config', slug: 'guides/mutual' }, 74 74 { label: 'Custom Nix Classes', slug: 'guides/custom-classes' }, 75 75 { label: 'Homes Integration', slug: 'guides/home-manager' }, 76 76 { label: 'Use Batteries', slug: 'guides/batteries' },
+6 -11
docs/src/content/docs/guides/batteries.mdx
··· 38 38 39 39 ### `den.provides.mutual-provider` 40 40 41 - Allows hosts and users to contribute configuration **to each other** through `provides`: 41 + Allows hosts and users to contribute configuration **to each other** through `.provides.`: 42 42 43 43 ```nix 44 44 den.hosts.x86_64-linux.igloo.users.tux = { }; 45 - den.default.includes = [ den._.mutual-provider ]; 45 + den.ctx.user.includes = [ den._.mutual-provider ]; 46 46 ``` 47 47 48 - This is not the same as the built-in bidirectionality: 49 - 50 48 ```nix 51 49 # contributes to ALL users of this host 52 - den.aspects.my-host.homeManager = { ... } 50 + den.aspects.my-host.provides.to-users.homeManager = { ... } 53 51 54 52 # contributes to ALL hosts of where my-user exist 55 - den.aspects.my-user.nixos = { ... } 53 + den.aspects.my-user.provides.to-hosts.nixos = { ... } 56 54 ``` 57 55 58 - The difference is that this allows you to wire bidirectionality between 59 - explictly-named hosts/users pairs. 60 - 61 - A user providing config TO the host: 56 + A `tux` user providing config to **specific host** `igloo`: 62 57 63 58 ```nix 64 59 den.aspects.tux = { ··· 68 63 }; 69 64 ``` 70 65 71 - A host providing config TO the user: 66 + A host providing config to **specific user** `tux`: 72 67 73 68 ```nix 74 69 den.aspects.igloo = {
-280
docs/src/content/docs/guides/bidirectional.mdx
··· 1 - --- 2 - title: Host<->User Bidirectionality 3 - description: How to configure bidirectional behavior in Den. 4 - --- 5 - 6 - import { Aside } from '@astrojs/starlight/components'; 7 - 8 - <Aside title="Source" icon="github"> 9 - [`context/user.nix`](https://github.com/vic/den/blob/main/modules/context/user.nix) · 10 - [`context/host.nix`](https://github.com/vic/den/blob/main/modules/context/host.nix) · 11 - [`bidirectional.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/bidirectional.nix) · 12 - [`mutual-provider.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix) 13 - </Aside> 14 - 15 - ## What Bidirectionality Means 16 - 17 - __Bidirectionality__ means that not only a User contributes 18 - configuration to a Host, but **also** that a Host contributes 19 - configurations to a User. 20 - 21 - <Aside title="When is bidirectionality needed?" icon="comment-alt"> 22 - Only when you wish for a Host-aspect to provide common _home settings_ 23 - (`homeManager`, etc) for **all** its users. 24 - 25 - And even then there are much simpler and better ways: 26 - 27 - ```nix 28 - # an aspect with all common stuff for everybody 29 - den.aspects.user-base = { nixos = ...; homeManager = ...; hjem = ...; }; 30 - 31 - # include it in all users 32 - den.ctx.user.includes = [ den.aspects.user-base ]; 33 - ``` 34 - 35 - > _Now you can skip the rest of this page_. 36 - </Aside> 37 - 38 - 39 - There are at least two (built-in) ways to achieve this in Den. 40 - The `den._.bidirectional` and `den._.mutual-provider` batteries. The 41 - first one was extracted from den-core and the second started 42 - life as an **aspect routing** example, but made it to become 43 - proper battery itself and even safer than the first. 44 - 45 - 46 - ## Default, *unidirectional* OS configuration 47 - 48 - Den framework is built around **context pipeline** transformations. 49 - In order to create a full OS configuration, everything starts with a host definition: 50 - 51 - ```nix "igloo" "tux" 52 - den.hostx.x86_64-linux.igloo.users.tux = {} 53 - ``` 54 - 55 - We need to build the `nixos` Nix module that will later be used by `lib.nixosSystem`. 56 - To do so, Den invokes the `den.ctx.host` pipeline like this: 57 - 58 - > `Tip: Zoom diagrams using your mouse wheel or drag to move.` 59 - 60 - ```mermaid 61 - sequenceDiagram 62 - participant Den 63 - participant host as den.ctx.host 64 - participant user as den.ctx.user 65 - participant igloo as den.aspects.igloo 66 - participant tux as den.aspects.tux 67 - 68 - Den ->> host : {host = igloo} 69 - 70 - host ->> igloo : request nixos class 71 - igloo -->> igloo : each .includes takes { host } 72 - igloo -->> host : { nixos = ... } owned and parametric results 73 - 74 - host ->> user : fan-outs for each user: { host, user } 75 - 76 - user ->> tux : request nixos class 77 - tux -->> tux : home classes forwarded as nixos class 78 - tux -->> tux : each .includes takes { host, user } 79 - tux -->> user : { nixos = ... } owned and parametric results 80 - 81 - user -->> host : { nixos = ... } all user contributions 82 - 83 - host -->> Den : complete nixos module for lib.nixosSystem 84 - 85 - ``` 86 - 87 - This is the normal NixOS pipeline an __Not Bidirectional__. All OS contributions come from 88 - the host itself and from each of its user. 89 - 90 - 91 - 92 - ## `den.provides.bidirectional` 93 - 94 - Bidirectionality is enabled __per-user__ or for _all_ of them. 95 - 96 - ```nix 97 - # only tux takes configurations from its hosts 98 - den.aspects.tux.includes = [ den._.bidirectional ]; 99 - 100 - # for ALL users 101 - den.ctx.user.includes = [ den._.bidirectional ]; 102 - ``` 103 - 104 - When Bidirectionality is enabled, the interaction looks like this: 105 - 106 - > `Tip: Zoom diagrams using your mouse wheel or drag to move.` 107 - 108 - ```mermaid 109 - sequenceDiagram 110 - participant Den 111 - participant host as den.ctx.host 112 - participant user as den.ctx.user 113 - participant igloo as den.aspects.igloo 114 - participant tux as den.aspects.tux 115 - 116 - Den ->> host : {host = igloo} 117 - 118 - host ->> igloo : request nixos class 119 - igloo -->> igloo : each .includes takes { host } 120 - igloo -->> host : { nixos = ... } owned and parametric results 121 - 122 - host ->> user : fan-outs for each user: { host, user } 123 - 124 - user ->> tux : request nixos class 125 - 126 - tux ->> igloo : request home class 127 - igloo -->> igloo : each .includes takes { host, user } 128 - igloo -->> tux : { hjem = ... } owned and parametric results 129 - 130 - tux -->> tux : home classes forwarded as nixos class 131 - 132 - tux -->> tux : each .includes takes { host, user } 133 - tux -->> user : { nixos = ... } owned and parametric results 134 - 135 - user -->> host : { nixos = ... } all user contributions 136 - 137 - host -->> Den : complete nixos module for lib.nixosSystem 138 - 139 - ``` 140 - 141 - <Aside title="Potential Duplicates by Host Aspect" type="caution"> 142 - **Under Bidirectionality**, the igloo aspect is activated more than once! 143 - 144 - Notice that `den.aspects.igloo.includes` functions are called **with** `{ host }` and **later with** `{ host, user }` **per-user**. 145 - 146 - Because the list of functions at `igloo.includes` get invoked more than once, with different contexts, 147 - they must take care of the following: 148 - 149 - ```nix 150 - # avoid being called with `{host, user}` 151 - den.lib.perHost ({ host }: ...) 152 - 153 - # avoid being called with `{host}` 154 - den.lib.perUser ({ host, user }: ...) 155 - ``` 156 - 157 - Static aspects (plain-attrsets) or host-owned classes at a Host-aspect 158 - have **no way** to distinguish when the calling context is 159 - `{host}` or `{host,user}`, **only functions** are context-aware. 160 - 161 - ``` 162 - # Lists, packages, options at host-level would cause duplicates 163 - # den.aspects.igloo.nixos.options.foo = lib.mkOption {}; 164 - 165 - # Instead, use perHost to define unique values: 166 - den.aspects.igloo.includes = [ 167 - (perHost { nixos.options.foo = lib.mkOption {}; }) 168 - ]; 169 - ``` 170 - 171 - Read the documentation at [`context/user.nix`](https://github.com/vic/den/blob/main/modules/context/user.nix) for all the details. 172 - </Aside> 173 - 174 - <Aside title="Avoid dups with host-only module pattern" icon="rocket"> 175 - Here's a pattern you can use to avoid duplication while `bidirectional` is enabled: 176 - 177 - ```nix 178 - den.aspects.igloo.includes = [ 179 - # wrap an aspect with perHost 180 - (den.lib.perHost igloo-only) 181 - 182 - # any other aspect can contribute to users 183 - shells 184 - music-production 185 - ]; 186 - 187 - # Use this aspect for host-only stuff, anything that would 188 - # lead to duplicates is safe in this list 189 - den.aspects.igloo-only = { 190 - includes = with den.aspects; [ facter disko ]; 191 - nixos = { pkgs, ... }: { 192 - environment.systemPackages = [ pkgs.hello ]; 193 - }; 194 - } 195 - ``` 196 - 197 - > Tip inspired by `@drupol`. 198 - </Aside> 199 - 200 - ## `den.provides.mutual-provider` 201 - 202 - An alternative to bidirectionality is [`den.provides.mutual-provider`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix). 203 - 204 - This battery is safer, instead of using the host aspect directly, it requires you to define other named aspects under `.provides.` to create an explicit relationship between users and hosts. 205 - 206 - ```nix 207 - # mutual-provider is activated at a `{host,user}` context 208 - den.ctx.user.includes = [ den._.mutual-provider ]; 209 - 210 - # user aspect provides to specific host or to all where it lives 211 - den.aspects.tux = { 212 - provides.igloo.nixos.programs.emacs.enable = true; 213 - provides.to-hosts = { host, ... }: { 214 - nixos.programs.nh.enable = host.name == "igloo"; 215 - }; 216 - }; 217 - 218 - # host aspect provides to specific user or to all its users 219 - den.aspects.igloo = { 220 - provides.alice.homeManager.programs.vim.enable = true; 221 - provides.to-users = { user, ... }: { 222 - homeManager.programs.helix.enable = user.name == "alice"; 223 - }; 224 - }; 225 - ``` 226 - 227 - > `Tip: Zoom diagrams using your mouse wheel or drag to move.` 228 - 229 - ```mermaid 230 - sequenceDiagram 231 - participant Den 232 - participant host as den.ctx.host 233 - participant user as den.ctx.user 234 - participant igloo as den.aspects.igloo 235 - participant igloo-users as den.aspects.igloo.provides.to-users 236 - participant igloo-tux as den.aspects.igloo.provides.tux 237 - participant tux as den.aspects.tux 238 - participant tux-hosts as den.aspects.tux.provides.to-hosts 239 - participant tux-igloo as den.aspects.tux.provides.igloo 240 - 241 - Den ->> host : {host = igloo} 242 - 243 - host ->> igloo : request nixos class 244 - igloo -->> igloo : each .includes takes { host } 245 - igloo -->> host : { nixos = ... } owned and parametric results 246 - 247 - host ->> user : fan-outs for each user: { host, user } 248 - 249 - user ->> tux : request nixos class 250 - tux -->> tux : home classes forwarded as nixos class 251 - tux -->> tux : each .includes takes { host, user } 252 - tux -->> user : { nixos = ... } owned and parametric results 253 - 254 - user ->> igloo-users : host configs its users: { host, user } 255 - igloo-users -->> igloo-users : home classes forwarded as nixos class 256 - igloo-users -->> igloo-users : each .includes takes { host, user } 257 - igloo-users -->> user : { nixos = ... } 258 - 259 - user ->> igloo-tux : host configs tux: { host, user } 260 - igloo-tux -->> igloo-tux : home classes forwarded as nixos class 261 - igloo-tux -->> igloo-tux : each .includes takes { host, user } 262 - igloo-tux -->> user : { nixos = ... } 263 - 264 - user ->> tux-hosts : user configs its hosts: { host, user } 265 - tux-hosts -->> tux-hosts : home classes forwarded as nixos class 266 - tux-hosts -->> tux-hosts : each .includes takes { host, user } 267 - tux-hosts -->> user : { nixos = ... } 268 - 269 - user ->> tux-igloo : user configs igloo: { host, user } 270 - tux-igloo -->> tux-igloo : home classes forwarded as nixos class 271 - tux-igloo -->> tux-igloo : each .includes takes { host, user } 272 - tux-igloo -->> user : { nixos = ... } 273 - 274 - 275 - user -->> host : { nixos = ... } all user contributions 276 - 277 - host -->> Den : complete nixos module for lib.nixosSystem 278 - 279 - ``` 280 -
+144
docs/src/content/docs/guides/mutual.mdx
··· 1 + --- 2 + title: Host<->User Mutual Providers 3 + description: How to configure mutual configs in Den. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside title="Source" icon="github"> 9 + [`context/user.nix`](https://github.com/vic/den/blob/main/modules/context/user.nix) · 10 + [`context/host.nix`](https://github.com/vic/den/blob/main/modules/context/host.nix) · 11 + [`mutual-provider.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix) 12 + </Aside> 13 + 14 + ## What Mutual-Config Mean 15 + 16 + __Mutual Configs__ means that not only a User contributes 17 + configuration to a Host, but **also** that a Host contributes 18 + configurations to a User. 19 + 20 + 21 + ## Default, *unidirectional* OS configuration 22 + 23 + Den framework is built around **context pipeline** transformations. 24 + In order to create a full OS configuration, everything starts with a host definition: 25 + 26 + ```nix "igloo" "tux" 27 + den.hostx.x86_64-linux.igloo.users.tux = {} 28 + ``` 29 + 30 + We need to build the `nixos` Nix module that will later be used by `lib.nixosSystem`. 31 + To do so, Den invokes the `den.ctx.host` pipeline like this: 32 + 33 + > `Tip: Zoom diagrams using your mouse wheel or drag to move.` 34 + 35 + ```mermaid 36 + sequenceDiagram 37 + participant Den 38 + participant host as den.ctx.host 39 + participant user as den.ctx.user 40 + participant igloo as den.aspects.igloo 41 + participant tux as den.aspects.tux 42 + 43 + Den ->> host : {host = igloo} 44 + 45 + host ->> igloo : request nixos class 46 + igloo -->> igloo : each .includes takes { host } 47 + igloo -->> host : { nixos = ... } owned and parametric results 48 + 49 + host ->> user : fan-outs for each user: { host, user } 50 + 51 + user ->> tux : request nixos class 52 + tux -->> tux : home classes forwarded as nixos class 53 + tux -->> tux : each .includes takes { host, user } 54 + tux -->> user : { nixos = ... } owned and parametric results 55 + 56 + user -->> host : { nixos = ... } all user contributions 57 + 58 + host -->> Den : complete nixos module for lib.nixosSystem 59 + 60 + ``` 61 + 62 + This is the normal `den.ctx.host` pipeline. All OS contributions come from the host itself and from each of its user. 63 + 64 + 65 + ## `den.provides.mutual-provider` 66 + 67 + The [`den.provides.mutual-provider`](https://github.com/vic/den/blob/main/modules/aspects/provides/mutual-provider.nix) battery allows you to define mutual congigurations by letting you to define named aspects under `.provides.` to create explicit relationship between users and hosts. 68 + 69 + ```nix 70 + # mutual-provider is activated at a `{host,user}` context 71 + # either per-user or for all of them. 72 + den.ctx.user.includes = [ den._.mutual-provider ]; 73 + 74 + # user aspect provides to specific host or to all where it lives 75 + den.aspects.tux = { 76 + provides.igloo.nixos.programs.emacs.enable = true; 77 + provides.to-hosts = { host, ... }: { 78 + nixos.programs.nh.enable = host.name == "igloo"; 79 + }; 80 + }; 81 + 82 + # host aspect provides to specific user or to all its users 83 + den.aspects.igloo = { 84 + provides.alice.homeManager.programs.vim.enable = true; 85 + provides.to-users = { user, ... }: { 86 + homeManager.programs.helix.enable = user.name == "alice"; 87 + }; 88 + }; 89 + ``` 90 + 91 + > `Tip: Zoom diagrams using your mouse wheel or drag to move.` 92 + 93 + ```mermaid 94 + sequenceDiagram 95 + participant Den 96 + participant host as den.ctx.host 97 + participant user as den.ctx.user 98 + participant igloo as den.aspects.igloo 99 + participant igloo-users as den.aspects.igloo.provides.to-users 100 + participant igloo-tux as den.aspects.igloo.provides.tux 101 + participant tux as den.aspects.tux 102 + participant tux-hosts as den.aspects.tux.provides.to-hosts 103 + participant tux-igloo as den.aspects.tux.provides.igloo 104 + 105 + Den ->> host : {host = igloo} 106 + 107 + host ->> igloo : request nixos class 108 + igloo -->> igloo : each .includes takes { host } 109 + igloo -->> host : { nixos = ... } owned and parametric results 110 + 111 + host ->> user : fan-outs for each user: { host, user } 112 + 113 + user ->> tux : request nixos class 114 + tux -->> tux : home classes forwarded as nixos class 115 + tux -->> tux : each .includes takes { host, user } 116 + tux -->> user : { nixos = ... } owned and parametric results 117 + 118 + user ->> igloo-users : host configs its users: { host, user } 119 + igloo-users -->> igloo-users : home classes forwarded as nixos class 120 + igloo-users -->> igloo-users : each .includes takes { host, user } 121 + igloo-users -->> user : { nixos = ... } 122 + 123 + user ->> igloo-tux : host configs tux: { host, user } 124 + igloo-tux -->> igloo-tux : home classes forwarded as nixos class 125 + igloo-tux -->> igloo-tux : each .includes takes { host, user } 126 + igloo-tux -->> user : { nixos = ... } 127 + 128 + user ->> tux-hosts : user configs its hosts: { host, user } 129 + tux-hosts -->> tux-hosts : home classes forwarded as nixos class 130 + tux-hosts -->> tux-hosts : each .includes takes { host, user } 131 + tux-hosts -->> user : { nixos = ... } 132 + 133 + user ->> tux-igloo : user configs igloo: { host, user } 134 + tux-igloo -->> tux-igloo : home classes forwarded as nixos class 135 + tux-igloo -->> tux-igloo : each .includes takes { host, user } 136 + tux-igloo -->> user : { nixos = ... } 137 + 138 + 139 + user -->> host : { nixos = ... } all user contributions 140 + 141 + host -->> Den : complete nixos module for lib.nixosSystem 142 + 143 + ``` 144 +
+1 -4
docs/src/content/docs/reference/batteries.mdx
··· 40 40 41 41 ### `den._.mutual-provider` 42 42 43 - Allows the user and host to contribute configuration to each other via 44 - `provides`. This is not the same as the built-in bidirectionality. The 45 - difference is that this allows you to wire bidirectionality between 46 - explictly-named hosts/users pairs. 43 + Allows the user and host to contribute configuration to each other via `.provides.`. 47 44 48 45 ### `den._.tty-autologin` 49 46
+2 -2
docs/src/content/docs/tutorials/ci.md
··· 27 27 schema-base-modules.nix # den.schema modules 28 28 special-args-custom-instantiate.nix # custom instantiation 29 29 top-level-parametric.nix # top-level context aspects 30 - user-host-bidirectional-config.nix # bidirectional providers 30 + user-host-mutual-config.nix # mutual providers 31 31 batteries/ 32 32 define-user.nix # define-user battery 33 33 flake-parts.nix # inputs' and self' ··· 70 70 71 71 | Test File | What It Tests | 72 72 |-----------|---------------| 73 - | [user-host-bidirectional-config.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/user-host-bidirectional-config.nix) | Host→user and user→host config flow | 73 + | [user-host-mutual-config.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/user-host-mutual-config.nix) | Host→user and user→host config flow | 74 74 | [context/cross-provider.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/context/cross-provider.nix) | Source providing config to target context | 75 75 | [context/named-provider.nix](https://github.com/vic/den/blob/main/templates/ci/modules/features/context/named-provider.nix) | Self-named provider mechanism | 76 76
-16
modules/aspects/provides/bidirectional.nix
··· 1 - { den, ... }: 2 - let 3 - description = '' 4 - Enable Den bidirectionality: User takes configuration from Host. 5 - 6 - **REALLY** IMPORTANT: Read the documentation for den.ctx.user 7 - 8 - Consider as alternative den.provides.mutual-provider. 9 - ''; 10 - in 11 - { 12 - den.provides.bidirectional = { 13 - inherit description; 14 - includes = [ den.ctx.user.provides.bidirectional ]; 15 - }; 16 - }
+1 -6
modules/aspects/provides/mutual-provider.nix
··· 9 9 10 10 This battery implements an aspect "routing" pattern. 11 11 12 - This is not the same as `den._.bidirectional` battery, but provides a 13 - **safer** alternative to `den._.bidirectional`. 14 - The reason is that this battery does not re-invoke the `host-aspect.includes`, 15 - instead it relies on you defining provides. 16 - 17 12 Be sure to read diagrams for the Host context pipeline: 18 - https://den.oeiuwq.com/guides/bidirectional 13 + https://den.oeiuwq.com/guides/mutual 19 14 20 15 ## Usage 21 16
-47
modules/context/user.nix
··· 23 23 - static includes like { nixos.foo = ... } or ({ class, aspect-chain }: { nixos.foo = ...; }) 24 24 - atLeast{host,user} parametric includes like ({ host,user }: { nixos.foo = ...; }) 25 25 26 - ## Bidirectionality 27 - 28 - Battery `den.provides.bidirectional` can be included on each user that needs to take configuration from the Host. 29 - 30 - Enable per user: 31 - den.aspects.tux.includes = [ den._.bidirectional ]; 32 - 33 - Enable for all users: 34 - den.ctx.user.includes = [ den._.bidirectional ]; 35 - 36 - IMPORTANT: Enabling bidirectionality means that the following pipeline is enabled: 37 - 38 - host-aspect{host} => user-aspect{host,user} => host-aspect{host,user} 39 - 40 - Notice that the host-aspect is being activated more than once! 41 - 42 - This means that host configurations are obtained 43 - - once when the host is obtaining its own configuration with context {host} 44 - - once PER user that has bidirectionality enabled with context {host,user} 45 - 46 - Due to Nix `lib.functionArgs` not distinguishing between `{host}` and `{host, ...}`, 47 - Den provides these utilities built upon `den.lib.take.exactly`: 48 - 49 - # Do this to prevent being invoked with `{host,user}` 50 - den.lib.perHost ({host}: ...) 51 - 52 - # Do this to prevent being invoked with `{host}` 53 - den.lib.perUser ({host,user}: ...) 54 - 55 - Static aspects (plain-attrsets) or host-owned classes at a Host-aspect 56 - have **no way** to distinguish when the calling context is 57 - `{host}` or `{host,user}`, only functions are context-aware. 58 - 59 - Because of this, a host-aspect might produce duplicate values on list, 60 - package types, or unique values like options: 61 - 62 - # lists, packages and options need to be unique. 63 - # this line would produce duplicate errors IF bidirectional enabled 64 - den.aspects.igloo.nixos.options.foo = lib.mkOption {}; 65 - 66 - # Instead, wrap in perHost things that must be unique 67 - den.aspects.igloo.includes = [ 68 - (den.lib.perHost { nixos.options.foo = lib.mkOption {}; }) 69 - ] 70 26 ''; 71 27 72 28 ctx.user.into.default = lib.singleton; 73 29 ctx.user.provides.user = take.exactly from-user; 74 - ctx.user.provides.bidirectional = take.exactly from-host; 75 30 76 31 from-user = { host, user }: fixedTo { inherit host user; } den.aspects.${user.aspect}; 77 - 78 - from-host = { host, user }: fixedTo { inherit host user; } den.aspects.${host.aspect}; 79 32 80 33 in 81 34 {
+9 -7
templates/ci/modules/features/auto-parametric.nix
··· 69 69 test-explicit-exactly-not-overridden-by-default = denTest ( 70 70 { den, igloo, ... }: 71 71 { 72 - den.ctx.user.includes = [ den._.bidirectional ]; 72 + den.hosts.x86_64-linux.igloo.users.tux = { }; 73 + 73 74 den.aspects.strict-helper = den.lib.parametric.exactly { 74 75 includes = [ 75 76 ( ··· 80 81 ) 81 82 ]; 82 83 }; 83 - den.aspects.igloo.includes = [ den.aspects.strict-helper ]; 84 - den.hosts.x86_64-linux.igloo.users.tux = { }; 84 + 85 + den.ctx.user.includes = [ den._.mutual-provider ]; 86 + den.aspects.igloo._.to-users.includes = [ den.aspects.strict-helper ]; 85 87 86 88 # strict-helper requires exactly { host, user } — since ctx.host only provides 87 89 # { host }, strict-helper is skipped at host level (by exactly semantics). ··· 110 112 test-second-level-helper-owned-config-preserved = denTest ( 111 113 { den, igloo, ... }: 112 114 { 113 - den.ctx.user.includes = [ den._.bidirectional ]; 115 + den.ctx.user.includes = [ den._.mutual-provider ]; 114 116 den.hosts.x86_64-linux.igloo.users.tux = { }; 115 117 116 118 den.aspects.second-with-owned = { ··· 125 127 ]; 126 128 }; 127 129 den.aspects.helper.includes = [ den.aspects.second-with-owned ]; 128 - den.aspects.igloo.includes = [ den.aspects.helper ]; 130 + den.aspects.igloo._.to-users.includes = [ den.aspects.helper ]; 129 131 130 132 expr = [ 131 133 igloo.networking.hostName ··· 141 143 test-second-provides-helper-owned-config-preserved = denTest ( 142 144 { den, igloo, ... }: 143 145 { 144 - den.ctx.user.includes = [ den._.bidirectional ]; 146 + den.ctx.user.includes = [ den._.mutual-provider ]; 145 147 den.hosts.x86_64-linux.igloo.users.tux = { }; 146 148 147 149 den.aspects.second.provides.with-owned = { ··· 156 158 ]; 157 159 }; 158 160 den.aspects.helper.includes = [ den.aspects.second.provides.with-owned ]; 159 - den.aspects.igloo.includes = [ den.aspects.helper ]; 161 + den.aspects.igloo._.to-users.includes = [ den.aspects.helper ]; 160 162 161 163 expr = [ 162 164 igloo.networking.hostName
+2 -2
templates/ci/modules/features/batteries/define-user.nix
··· 25 25 }: 26 26 { 27 27 den.hosts.x86_64-linux.igloo.users.tux = { }; 28 - den.aspects.igloo.includes = [ den._.define-user ]; 29 - den.ctx.user.includes = [ den._.bidirectional ]; 28 + den.ctx.user.includes = [ den._.mutual-provider ]; 29 + den.aspects.igloo._.to-users.includes = [ den._.define-user ]; 30 30 expr = igloo.users.users.tux.isNormalUser; 31 31 expected = true; 32 32 }
+5 -4
templates/ci/modules/features/conditional-config.nix
··· 41 41 users.tux.hasBar = true; 42 42 }; 43 43 44 - den.ctx.user.includes = [ den._.bidirectional ]; 44 + den.ctx.user.includes = [ den._.mutual-provider ]; 45 45 46 - den.aspects.igloo.includes = [ conditionalAspect ]; 46 + den.aspects.igloo._.to-users.includes = [ conditionalAspect ]; 47 47 48 48 expr = igloo.something; 49 49 expected = "was-true"; ··· 68 68 tux = { }; 69 69 pingu = { }; 70 70 }; 71 + 71 72 den.default.homeManager.home.stateVersion = "25.11"; 72 - den.ctx.user.includes = [ den._.bidirectional ]; 73 - den.aspects.igloo.includes = [ git-for-linux-only ]; 73 + den.ctx.user.includes = [ den._.mutual-provider ]; 74 + den.aspects.igloo._.to-users.includes = [ git-for-linux-only ]; 74 75 75 76 expr = [ 76 77 tuxHm.programs.git.enable
+20 -18
templates/ci/modules/features/context/host-propagation.nix
··· 20 20 { 21 21 22 22 den.hosts.x86_64-linux.igloo.users.tux = { }; 23 - den.ctx.user.includes = [ den._.bidirectional ]; 23 + den.ctx.user.includes = [ den._.mutual-provider ]; 24 24 25 25 den.aspects.igloo.funny.names = [ "host-owned" ]; 26 26 den.aspects.igloo.includes = [ 27 + (take.exactly ( 28 + { host }: 29 + { 30 + funny.names = [ "host-exact" ]; 31 + } 32 + )) 33 + (take.exactly ( 34 + { host, user }: 35 + { 36 + funny.names = throw "unreachable"; 37 + } 38 + )) 39 + ]; 40 + den.aspects.igloo._.to-users.includes = [ 27 41 { funny.names = [ "host-static" ]; } 28 42 29 43 ( ··· 32 46 funny.names = [ "host-lax ${keys ctx}" ]; 33 47 } 34 48 ) 35 - (take.exactly ( 36 - { host }: 37 - { 38 - funny.names = [ "host-exact" ]; 39 - } 40 - )) 41 49 (take.atLeast ( 42 50 { host, never }: 43 51 { 44 - funny.names = [ "host-never" ]; 52 + funny.names = throw "unreachable"; 45 53 } 46 54 )) 47 55 ··· 64 72 never, 65 73 }: 66 74 { 67 - funny.names = [ "host+user-never" ]; 75 + funny.names = throw "unreachable"; 68 76 } 69 77 )) 70 78 ]; ··· 92 100 never, 93 101 }: 94 102 { 95 - funny.names = [ "user-never" ]; 103 + funny.names = throw "unreachable"; 96 104 } 97 105 )) 98 106 ]; ··· 139 147 funny.names = [ "default-host+user-lax ${keys ctx}" ]; 140 148 } 141 149 ) 142 - 143 - # the following error means an aspect is not parametric but static. (document this) 144 - # > error: function 'anonymous lambda' called without required argument 'user' 145 150 ]; 146 151 147 152 expr = funnyNames ( ··· 174 179 175 180 "host-exact" 176 181 "host-lax {host,user}" 177 - "host-lax {host}" 178 182 179 - "host-owned" # host 180 - "host-owned" # user bidirectional 181 - "host-static" # host 182 - "host-static" # user bidirectional 183 + "host-owned" 184 + "host-static" 183 185 184 186 "user-exact" 185 187 "user-lax {host,user}"
+3 -3
templates/ci/modules/features/deadbugs/external-namespace-deep-aspect.nix
··· 1 1 { denTest, inputs, ... }: 2 2 { 3 3 4 - flake.tests.deadbugs.namespace-deep-aspect = { 4 + flake.tests.deadbugs-namespace-deep-aspect = { 5 5 6 6 test-tools-has-underscore = denTest ( 7 7 { provider, ... }: ··· 86 86 ]) 87 87 ]; 88 88 den.hosts.x86_64-linux.igloo.users.tux = { }; 89 - den.aspects.igloo.includes = [ provider.tools._.dev._.user-stamp ]; 90 - den.ctx.user.includes = [ den._.bidirectional ]; 89 + den.aspects.igloo._.to-users.includes = [ provider.tools._.dev._.user-stamp ]; 90 + den.ctx.user.includes = [ den._.mutual-provider ]; 91 91 expr = igloo.users.users.tux.description; 92 92 expected = "user-of-igloo"; 93 93 }
+2 -2
templates/ci/modules/features/deadbugs/issue-201-forward-multiple-users.nix
··· 13 13 }: 14 14 { 15 15 den.default.homeManager.home.stateVersion = "25.11"; 16 - den.ctx.user.includes = [ den._.bidirectional ]; 16 + den.ctx.user.includes = [ den._.mutual-provider ]; 17 17 18 18 den.hosts.x86_64-linux.igloo.users = { 19 19 tux = { }; 20 20 pingu = { }; 21 21 }; 22 22 23 - den.aspects.igloo.includes = [ 23 + den.aspects.igloo._.to-users.includes = [ 24 24 den._.define-user 25 25 den.aspects.set-user-desc 26 26 ];
+1 -1
templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-bidir-enabled.nix templates/ci/modules/features/deadbugs/issue-292-hm-used-when-no-mutual-enabled.nix
··· 2 2 { 3 3 flake.tests.deadbugs-issue-292 = { 4 4 5 - test-should-not-read-from-host-without-bidirectionality = denTest ( 5 + test-should-not-read-from-host-without-mutuality = denTest ( 6 6 { 7 7 den, 8 8 lib,
+13 -13
templates/ci/modules/features/deadbugs/issue-297-bidirectional-not-including-host-owned-and-included-statics.nix templates/ci/modules/features/deadbugs/issue-297-mutual-not-including-host-owned-and-included-statics.nix
··· 2 2 { 3 3 flake.tests.deadbugs-issue-297 = { 4 4 5 - test-bidirectional-host-owned = denTest ( 5 + test-mutual-host-owned = denTest ( 6 6 { 7 7 den, 8 8 lib, ··· 12 12 }: 13 13 { 14 14 den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; 15 - den.ctx.user.includes = [ den._.bidirectional ]; 15 + den.ctx.user.includes = [ den._.mutual-provider ]; 16 16 17 - den.aspects.igloo.homeManager.home.keyboard.model = "denkbd"; 17 + den.aspects.igloo._.to-users.homeManager.home.keyboard.model = "denkbd"; 18 18 19 19 expr = tuxHm.home.keyboard.model; 20 20 expected = "denkbd"; 21 21 } 22 22 ); 23 23 24 - test-bidirectional-host-included-statics = denTest ( 24 + test-mutual-host-included-statics = denTest ( 25 25 { 26 26 den, 27 27 lib, ··· 31 31 }: 32 32 { 33 33 den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; 34 - den.ctx.user.includes = [ den._.bidirectional ]; 34 + den.ctx.user.includes = [ den._.mutual-provider ]; 35 35 36 36 den.aspects.base.homeManager.home.keyboard.model = "denkbd"; 37 - den.aspects.igloo.includes = [ den.aspects.base ]; 37 + den.aspects.igloo._.to-users.includes = [ den.aspects.base ]; 38 38 39 39 expr = tuxHm.home.keyboard.model; 40 40 expected = "denkbd"; 41 41 } 42 42 ); 43 43 44 - test-bidirectional-host-owned-home-option = denTest ( 44 + test-mutual-host-owned-home-option = denTest ( 45 45 { 46 46 den, 47 47 lib, ··· 51 51 }: 52 52 { 53 53 den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; 54 - den.ctx.user.includes = [ den._.bidirectional ]; 54 + den.ctx.user.includes = [ den._.mutual-provider ]; 55 55 56 - den.aspects.igloo.homeManager.options.foo = lib.mkOption { default = "foo"; }; 56 + den.aspects.igloo._.to-users.homeManager.options.foo = lib.mkOption { default = "foo"; }; 57 57 58 58 expr = tuxHm.foo; 59 59 expected = "foo"; 60 60 } 61 61 ); 62 62 63 - test-bidirectional-host-owned-host-option = denTest ( 63 + test-mutual-host-owned-host-option = denTest ( 64 64 { 65 65 den, 66 66 lib, ··· 70 70 }: 71 71 { 72 72 den.hosts.x86_64-linux.igloo.users.tux.classes = [ "homeManager" ]; 73 - den.ctx.user.includes = [ den._.bidirectional ]; 73 + den.ctx.user.includes = [ den._.mutual-provider ]; 74 74 75 75 # NOTE: this causes an error: Option already defined! 76 - # This is because bidirectionality includes host configs again. 76 + # This is because mutuality includes host configs again. 77 77 # den.aspects.igloo.nixos.options.foo = lib.mkOption { default = "foo"; }; 78 - # NOTE: Under bidirectionality, use perHost 78 + # NOTE: Under mutuality, use perHost 79 79 den.aspects.igloo.includes = [ 80 80 (den.lib.perHost { 81 81 nixos.options.foo = lib.mkOption { default = "foo"; };
+2 -2
templates/ci/modules/features/host-options.nix
··· 56 56 { den, igloo, ... }: 57 57 { 58 58 den.hosts.x86_64-linux.igloo.users.tux.userName = "penguin"; 59 - den.aspects.igloo.includes = [ den._.define-user ]; 60 - den.ctx.user.includes = [ den._.bidirectional ]; 59 + den.aspects.igloo._.to-users.includes = [ den._.define-user ]; 60 + den.ctx.user.includes = [ den._.mutual-provider ]; 61 61 62 62 expr = igloo.users.users.penguin.isNormalUser; 63 63 expected = true;
+10 -15
templates/ci/modules/features/perUser-perHost.nix
··· 28 28 nixos.funny = [ "atHost perHost ${host.name} fun" ]; 29 29 } 30 30 )) 31 - (den.lib.perUser { nixos.funny = [ "atHost IGNORED perUser static" ]; }) 31 + (den.lib.perUser { nixos.funny = [ (throw "atHost IGNORED perUser static") ]; }) 32 32 (den.lib.perUser ( 33 33 { user, host }: 34 34 { 35 - nixos.funny = [ "atHost IGNORED perUser ${user.name}@${host.name} fun" ]; 35 + nixos.funny = [ (throw "atHost IGNORED perUser ${user.name}@${host.name} fun") ]; 36 36 } 37 37 )) 38 38 ]; 39 39 40 40 den.aspects.tux.includes = [ 41 - (den.lib.perHost { nixos.funny = [ "atUser IGNORED perHost static" ]; }) 41 + (den.lib.perHost { nixos.funny = [ (throw "atUser IGNORED perHost static") ]; }) 42 42 (den.lib.perHost ( 43 43 { host }: 44 44 { 45 - nixos.funny = [ "atUser IGNORED perHost ${host.name} fun" ]; 45 + nixos.funny = [ (throw "atUser IGNORED perHost ${host.name} fun") ]; 46 46 } 47 47 )) 48 48 (den.lib.perUser { nixos.funny = [ "atUser perUser static" ]; }) ··· 64 64 } 65 65 ); 66 66 67 - test-included-in-bidirectional-pipeline = denTest ( 67 + test-included-in-mutual-pipeline = denTest ( 68 68 { 69 69 den, 70 70 igloo, ··· 77 77 pingu = { }; 78 78 }; 79 79 80 - den.ctx.user.includes = [ den._.bidirectional ]; 80 + den.ctx.user.includes = [ den._.mutual-provider ]; 81 81 82 - # NOTE: Since options must be unique, include via perHost 83 - den.aspects.funMod.nixos.options.funny = lib.mkOption { 82 + den.aspects.igloo.nixos.options.funny = lib.mkOption { 84 83 default = [ ]; 85 84 type = lib.types.listOf lib.types.str; 86 85 }; 87 86 88 - den.aspects.igloo.includes = [ 89 - (den.lib.perHost den.aspects.funMod) 90 - 91 - (den.lib.perHost { nixos.funny = [ "atHost perHost static" ]; }) 87 + den.aspects.igloo._.to-users.includes = [ 88 + (den.lib.perHost { nixos.funny = [ (throw "atHost perHost static") ]; }) 92 89 (den.lib.perHost ( 93 90 { host }: 94 91 { 95 - nixos.funny = [ "atHost perHost ${host.name} fun" ]; 92 + nixos.funny = [ (throw "atHost perHost ${host.name} fun") ]; 96 93 } 97 94 )) 98 95 (den.lib.perUser { nixos.funny = [ "atHost perUser static" ]; }) ··· 129 126 "atHost perUser static" # tux 130 127 "atUser perUser tux@igloo fun" 131 128 "atUser perUser static" 132 - "atHost perHost igloo fun" 133 - "atHost perHost static" 134 129 ]; 135 130 } 136 131 );
+11 -11
templates/ci/modules/features/user-host-bidirectional-config.nix templates/ci/modules/features/user-host-mutual-config.nix
··· 1 1 { denTest, ... }: 2 2 { 3 - flake.tests.user-host-bidirectional-config = { 3 + flake.tests.user-host-mutual-config = { 4 4 5 5 test-host-owned-unidirectional = denTest ( 6 6 { ··· 15 15 pingu = { }; 16 16 }; 17 17 18 - # no bidirectionality enabled, this is ignored 18 + # no mutuality enabled, this is ignored 19 19 den.aspects.igloo.homeManager.programs.direnv.enable = true; 20 20 21 21 expr = [ ··· 29 29 } 30 30 ); 31 31 32 - test-host-owned-bidirectional = denTest ( 32 + test-host-owned-mutual = denTest ( 33 33 { 34 34 den, 35 35 tuxHm, ··· 42 42 pingu = { }; 43 43 }; 44 44 45 - den.ctx.user.includes = [ den._.bidirectional ]; 46 - den.aspects.igloo.homeManager.programs.direnv.enable = true; 45 + den.ctx.user.includes = [ den._.mutual-provider ]; 46 + den.aspects.igloo._.to-users.homeManager.programs.direnv.enable = true; 47 47 48 48 expr = [ 49 49 tuxHm.programs.direnv.enable ··· 56 56 } 57 57 ); 58 58 59 - test-host-bidirectional-static-includes-configures-all-users = denTest ( 59 + test-host-mutual-static-includes-configures-all-users = denTest ( 60 60 { 61 61 den, 62 62 tuxHm, ··· 69 69 pingu = { }; 70 70 }; 71 71 72 - den.ctx.user.includes = [ den._.bidirectional ]; 72 + den.ctx.user.includes = [ den._.mutual-provider ]; 73 73 74 - den.aspects.igloo.includes = [ 74 + den.aspects.igloo._.to-users.includes = [ 75 75 { 76 76 homeManager.programs.direnv.enable = true; 77 77 } ··· 122 122 } 123 123 ); 124 124 125 - test-host-parametric-bidirectional = denTest ( 125 + test-host-parametric-mutual = denTest ( 126 126 { 127 127 den, 128 128 tuxHm, ··· 136 136 pingu = { }; 137 137 }; 138 138 139 - den.ctx.user.includes = [ den._.bidirectional ]; 139 + den.ctx.user.includes = [ den._.mutual-provider ]; 140 140 141 - den.aspects.igloo.includes = [ 141 + den.aspects.igloo._.to-users.includes = [ 142 142 ( 143 143 { host, user }: 144 144 {