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
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}