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
at 2b001767fc6d4a9cc8a17d0d0d631561ba224a74 88 lines 2.3 kB view raw
1{ 2 lib, 3 config, 4 ... 5}: 6let 7 aspects = config.flake.aspects; 8 9 transpose = import ./. { inherit lib emit; }; 10 emit = transposed: [ 11 { 12 inherit (transposed) parent child; 13 value = aspectModule aspects.${transposed.child} transposed.parent; 14 } 15 ]; 16 17 aspectModule = 18 aspect: class: 19 let 20 require = f: aspectModule (f (aspect // { inherit class; })) class; 21 module.imports = lib.flatten [ 22 (aspect.${class} or { }) 23 (lib.map require aspect.requires) 24 ]; 25 in 26 module; 27 28 providerType = lib.types.functionTo aspectSubmoduleType; 29 30 aspectSubmoduleType = lib.types.submodule ( 31 { name, config, ... }: 32 { 33 freeformType = lib.types.lazyAttrsOf lib.types.deferredModule; 34 options.name = lib.mkOption { 35 readOnly = true; 36 description = "Aspect name"; 37 default = name; 38 type = lib.types.str; 39 }; 40 options.description = lib.mkOption { 41 description = "Aspect description"; 42 default = "Aspect ${name}"; 43 type = lib.types.str; 44 }; 45 options.requires = lib.mkOption { 46 description = "Providers to ask aspects from"; 47 type = lib.types.listOf providerType; 48 default = [ ]; 49 }; 50 options.provides = lib.mkOption { 51 description = "Providers of aspect for other aspects"; 52 default = { }; 53 type = lib.types.submodule { 54 freeformType = lib.types.lazyAttrsOf providerType; 55 options.itself = lib.mkOption { 56 readOnly = true; 57 description = "Provides itself"; 58 type = providerType; 59 default = _: config; 60 }; 61 }; 62 }; 63 options.__functor = lib.mkOption { 64 internal = true; 65 readOnly = true; 66 visible = false; 67 description = "Functor to default provider"; 68 type = lib.types.unspecified; 69 default = _: config.provides.itself; 70 }; 71 } 72 ); 73 74in 75{ 76 options.flake.aspects = lib.mkOption { 77 default = { }; 78 description = '' 79 Attribute set of `<aspect>.<class>` modules. 80 81 Convenience transposition of `flake.modules.<class>.<aspect>`. 82 ''; 83 type = lib.types.submodule { 84 freeformType = lib.types.lazyAttrsOf aspectSubmoduleType; 85 }; 86 }; 87 config.flake.modules = transpose aspects; 88}