fake.modules transposition for aspect-oriented Dendritic Nix. with cross-aspect dependencies. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ dendrix.oeiuwq.com/Dendritic.html
dendritic nix aspect oriented

providers type checks for class or aspect-chain args

+14 -16
+4 -4
README.md
··· 222 222 223 223 #### Parameterized Providers 224 224 225 - Providers can be implemented as curried functions, allowing you to create parameterized modules. All arguments must be explicitly named. This is useful for creating reusable configurations that can be customized at the inclusion site. 225 + Providers can be implemented as curried functions, allowing you to create parameterized modules. This is useful for creating reusable configurations that can be customized at the inclusion site. 226 226 227 - For a real-world example, see how `vic/den` [defines](https://github.com/vic/den/blob/main/nix/aspects.nix) `flake.aspects.default.host` and its [usage](https://github.com/vic/den/blob/main/templates/default/modules/_example/aspects.nix). 227 + For real-world examples, see how `vic/den` defines [auto-imports](https://github.com/vic/den/blob/main/modules/aspects/batteries/import-tree.nix) and [home-managed](https://github.com/vic/den/blob/main/modules/aspects/batteries/home-managed.nix) parametric aspects. 228 228 229 229 ```nix 230 230 flake.aspects = { aspects, ... }: { 231 231 system = { 232 232 nixos.system.stateVersion = "25.11"; 233 - provides.user = { userName }: { aspect-chain, class }: { 233 + provides.user = userName: { 234 234 darwin.system.primaryUser = userName; 235 235 nixos.users.${userName}.isNormalUser = true; 236 236 }; ··· 238 238 239 239 home-server.includes = [ 240 240 aspects.system 241 - (aspects.system.provides.user { userName = "bob"; }) 241 + (aspects.system.provides.user "bob") 242 242 ]; 243 243 } 244 244 ```
+6 -8
checkmate.nix
··· 303 303 provides = 304 304 { provides, ... }: 305 305 { 306 - three-and-four-and-five = _: { 306 + three-and-four-and-five = { 307 307 classOne.bar = [ "3" ]; 308 308 includes = [ 309 309 provides.four 310 310 aspects.five 311 311 ]; 312 312 }; 313 - four = _: { 313 + four = { 314 314 classOne.bar = [ "4" ]; 315 315 }; 316 316 }; ··· 339 339 flake.aspects = 340 340 { aspects, ... }: 341 341 { 342 - aspectOne.includes = [ (aspects.aspectTwo.provides.hello { world = "mundo"; }) ]; 342 + aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ]; 343 343 aspectOne.classOne.bar = [ "1" ]; 344 344 345 - aspectTwo.provides.hello = 346 - { world }: # args must always be named. 347 - _: { 348 - classOne.bar = [ world ]; 349 - }; 345 + aspectTwo.provides.hello = world: { 346 + classOne.bar = [ world ]; 347 + }; 350 348 }; 351 349 }; 352 350
+4 -4
nix/types.nix
··· 15 15 # { class, aspect-chain } => aspect-object 16 16 # { class, ... } => aspect-object 17 17 # { aspect-chain, ... } => aspect-object 18 - # name => aspect-object 19 18 functionToAspect = lib.types.addCheck (lib.types.functionTo aspectSubmodule) ( 20 19 f: 21 20 let 22 21 args = lib.functionArgs f; 23 22 arity = lib.length (lib.attrNames args); 24 - isEmpty = arity == 0; 25 23 hasClass = args ? class; 26 24 hasChain = args ? aspect-chain; 27 25 classOnly = hasClass && arity == 1; 28 26 chainOnly = hasChain && arity == 1; 29 27 both = hasClass && hasChain && arity == 2; 30 28 in 31 - isEmpty || classOnly || chainOnly || both 29 + classOnly || chainOnly || both 32 30 ); 33 31 34 32 functionProviderType = lib.types.either functionToAspect (lib.types.functionTo providerType); ··· 72 70 readOnly = true; 73 71 description = "Provides itself"; 74 72 type = providerType; 75 - default = _: aspect; 73 + default = 74 + # deadnix: skip 75 + { class, ... }: aspect; 76 76 }; 77 77 } 78 78 );