310 lines
11 KiB
Nix
310 lines
11 KiB
Nix
{ core, context, extendPath, ... }:
|
|
{ ... } @ env:
|
|
{ configuration, options, source } @ self:
|
|
let
|
|
inherit(core) debug list set string type;
|
|
|
|
collect
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
debug.info "collect"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = configuration;
|
|
}
|
|
(
|
|
let
|
|
cfg = import configuration;
|
|
src = configuration;
|
|
fail
|
|
= typeName:
|
|
debug.panic
|
|
"collect"
|
|
"Got ${typeName} ${string configuration}, what should I do with it?";
|
|
in
|
|
type.matchPrimitive configuration
|
|
{
|
|
bool = fail "boolean";
|
|
float = fail "float";
|
|
int = fail "integer";
|
|
lambda = collectRegular state { inherit configuration source; };
|
|
list = collectList state { inherit configuration source; };
|
|
null = state; # Just Ignore
|
|
path = collect state { configuration = cfg; source = src; };
|
|
set = collectSet state configuration;
|
|
string = collect state { configuration = cfg; source = src; };
|
|
}
|
|
);
|
|
|
|
collectImports
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
debug.info "collectImports"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = configuration;
|
|
}
|
|
(
|
|
let
|
|
cfg = import configuration;
|
|
src = configuration;
|
|
in
|
|
type.matchPrimitiveOrPanic configuration
|
|
{
|
|
lambda = collectLegacy state { inherit configuration source; };
|
|
path = collectImports state { configuration = cfg; source = src; };
|
|
string = collectImports state { configuration = cfg; source = src; };
|
|
}
|
|
);
|
|
|
|
collectLegacy
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
let
|
|
legacyConfig
|
|
= configuration
|
|
{
|
|
inherit(finalState) config;
|
|
inherit(env.nixpkgs) lib;
|
|
pkgs = env.registries.nix.packages;
|
|
};
|
|
state'
|
|
= list.fold
|
|
(collectImports source)
|
|
state
|
|
(legacyConfig.imports or []);
|
|
in
|
|
combine
|
|
state'
|
|
{
|
|
configuration = set.remove legacyConfig [ "imports" ];
|
|
inherit source;
|
|
};
|
|
|
|
collectList
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
debug.info "collectList"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = configuration;
|
|
;
|
|
}
|
|
(
|
|
list.fold
|
|
(
|
|
state:
|
|
configuration:
|
|
collect state { inherit configuration source; }
|
|
)
|
|
state
|
|
configuration
|
|
);
|
|
|
|
collectRegular
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
let
|
|
regularConfig
|
|
= configuration
|
|
{
|
|
inherit(env) core dateTime host registries;
|
|
config
|
|
= debug.warn
|
|
"collectRegular"
|
|
"Use of `config` is deprecated!"
|
|
finalState.config;
|
|
};
|
|
in
|
|
debug.info "collectRegular"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = configuration;
|
|
}
|
|
(
|
|
combine
|
|
state
|
|
{
|
|
configuration = regularConfig;
|
|
inherit source;
|
|
}
|
|
);
|
|
|
|
collectService
|
|
= { ... } @ state:
|
|
{ configuration, source }:
|
|
let
|
|
serviceConfig
|
|
= configuration
|
|
{
|
|
inherit(env) core dateTime host registries;
|
|
inherit(finalState.config) services;
|
|
};
|
|
in
|
|
debug.info "collectService"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = configuration;
|
|
}
|
|
(
|
|
type.matchPrimitiveOrPanic configuration
|
|
{
|
|
lambda = combine state { configuration = serviceConfig; inherit source; };
|
|
set = combine state { inherit configuration source; };
|
|
}
|
|
);
|
|
|
|
collectSet
|
|
= { ... } @ state:
|
|
{ __type__ ? null, ... } @ self:
|
|
let
|
|
source = set.getSource self;
|
|
in
|
|
if __type__ == "Configuration" then collectSpecial state self
|
|
else if __type__ == null then combine state { configuration = self; inherit source; }
|
|
else
|
|
debug.panic
|
|
"collectSet"
|
|
"Unexpected Object of type ${__type__}. `Configuration` was expected";
|
|
|
|
collectSpecial
|
|
= { ... } @ state:
|
|
{
|
|
__variant__ ?
|
|
(
|
|
debug.panic
|
|
"collectSpecial"
|
|
"Missing `__variant__`, type `Configuration` is an enum-type!"
|
|
),
|
|
source ? null,
|
|
...
|
|
} @ self:
|
|
debug.info "collectSpecial"
|
|
{
|
|
text = "from ${toString source}";
|
|
data = __variant__;
|
|
}
|
|
(
|
|
{
|
|
Legacy = collectLegacy state self;
|
|
Service = collectService state self;
|
|
User = collectUser state self;
|
|
}.${__variant__}
|
|
);
|
|
|
|
collectUser
|
|
= { ... } @ state:
|
|
{ configuration, source, user }:
|
|
let
|
|
userConfig
|
|
= configuration
|
|
{
|
|
inherit(env) core dateTime home-manager profile registries;
|
|
config = userConfig;
|
|
user = user // { config = userConfig; };
|
|
};
|
|
in
|
|
debug.info "collectUser"
|
|
{
|
|
text = "from ${toString source} (${user.name})";
|
|
data = configuration;
|
|
}
|
|
(
|
|
type.matchPrimitiveOrPanic configuration
|
|
{
|
|
lambda = combine state { configuration = userConfig; inherit source; };
|
|
set = combine state { inherit configuration source; };
|
|
}
|
|
);
|
|
|
|
combine
|
|
= { options, path, ... } @ state:
|
|
{ configuration, source }:
|
|
let
|
|
combine = set.fold merge;
|
|
merge
|
|
= { config, options, path, ... } @ state:
|
|
name:
|
|
value:
|
|
let
|
|
path' = extendPath path name;
|
|
in
|
|
debug.info [ "combine" "merge" ]
|
|
{
|
|
text = path';
|
|
data = value;
|
|
}
|
|
(
|
|
if set.hasAttribute name options
|
|
then
|
|
let
|
|
configuration = value;
|
|
file = source;
|
|
option = options.${name};
|
|
values = config.${name} or [];
|
|
in
|
|
(
|
|
if option.__type__ or null == "Option"
|
|
then
|
|
config
|
|
// {
|
|
${name}
|
|
= values
|
|
++ [ { inherit file value; } ];
|
|
}
|
|
else
|
|
if type.isSet value
|
|
then
|
|
combine
|
|
{
|
|
config = config.${name};
|
|
options = option;
|
|
path = path';
|
|
}
|
|
{ inherit configuration source; }
|
|
else
|
|
debug.panic
|
|
[ "combine" "merge" ]
|
|
{
|
|
text
|
|
= ''
|
|
Option `${path'}` is an attribute set.
|
|
It cannot be combined with a `${type.getPrimitive value}`
|
|
'';
|
|
data = option;
|
|
}
|
|
)
|
|
else
|
|
debug.panic
|
|
[ "combine" "merge" ]
|
|
"Unknown option `${path'}` in ${source}"
|
|
);
|
|
in
|
|
debug.info "combine"
|
|
{
|
|
text = "${toString source}";
|
|
data = configuration;
|
|
}
|
|
(
|
|
state
|
|
// {
|
|
config = combine state configuration;
|
|
}
|
|
);
|
|
|
|
finalState
|
|
= collect
|
|
{
|
|
inherit options;
|
|
config = {};
|
|
path = null;
|
|
}
|
|
self;
|
|
in
|
|
debug.info []
|
|
{
|
|
text = "options";
|
|
data = set.names options;
|
|
}
|
|
finalState
|