blob: 1a606a510fdc8091a6d5b2840eeca0eeb336c5ae [file] [log] [blame]
# As our modules have nonstandard properties, we need to have some way of
# properly intepreting them
# This function takes a list of modules, as well as arguments to import them
# with, and returns a list of modules, each with the standard NixOS module
# properties as well as with custom properties as described in /README.md
lib: transformArgs: modules: args @ { pkgs, ... }:
let
resolver = module:
let
importedModule =
if builtins.typeOf module == "path"
then import module
else module;
resolvedModule =
if builtins.typeOf importedModule == "lambda"
then
importedModule
(transformArgs args)
else importedModule;
moduleName =
if builtins.typeOf module == "lambda"
then "<AnonFunction>"
else if builtins.typeOf module == "path"
then builtins.toString module
else builtins.toJSON module;
in
lib.warnIfNot
((lib.pipe resolvedModule [
builtins.attrNames
(lib.subtractLists [ "home" "config" "imports" "options" "traces" ])
])
== [ ])
"Module ${moduleName} had attribute names ${builtins.toJSON (builtins.attrNames resolvedModule)} but only home, config, imports and options are resolved"
[
{
config = lib.recursiveUpdate (resolvedModule.config or { }) {
home-manager.users."${args.username}".imports =
(resolvedModule.config.home-manager.users."${args.username}".imports or [ ])
++ [ resolvedModule.home or { } ];
};
imports = resolvedModule.imports or [ ];
options = resolvedModule.options or { };
}
]
++ (builtins.map
(trace:
let
splitTrace = lib.splitString "." trace;
traceHead = builtins.head splitTrace;
traceTail = builtins.tail splitTrace;
resolvedTrace =
(
if traceHead == "home"
then [ "home-manager" "users" args.username ]
else lib.errorIfNot (traceHead == "config") [ ]
)
++ traceTail;
in
{ config, ... }: (builtins.seq
(
lib.pipe resolvedTrace [
(lib.foldl
({ value
, error
,
}: key:
if builtins.hasAttr key value
then {
value = value.${key};
inherit error;
}
else {
value = { };
error = true;
})
{
value = { };
error = false;
})
(data: lib.warnIf data.error "trace@${moduleName}/${trace} is invalid; the key does not exist" data)
({ value
, error
,
}: {
value = builtins.toJSON value;
inherit error;
})
({ value
, error
,
}: {
value = "trace@${moduleName}/${trace}: ${value}";
inherit error;
})
({ value
, error
,
}:
lib.traceIf (!error) value null)
]
)
{ }))
(resolvedModule.traces or [ ]));
in
{
imports = (
if builtins.typeOf modules == "list"
then builtins.concatLists (builtins.map resolver modules)
else resolver modules
);
}