blob: 1a606a510fdc8091a6d5b2840eeca0eeb336c5ae [file] [log] [blame]
Skyler Grey51e18512022-08-20 12:24:19 +01001# As our modules have nonstandard properties, we need to have some way of
2# properly intepreting them
3# This function takes a list of modules, as well as arguments to import them
4# with, and returns a list of modules, each with the standard NixOS module
5# properties as well as with custom properties as described in /README.md
Skyler Grey252927a2022-10-18 22:18:15 +01006lib: transformArgs: modules: args @ { pkgs, ... }:
7let
8 resolver = module:
9 let
10 importedModule =
11 if builtins.typeOf module == "path"
12 then import module
13 else module;
14 resolvedModule =
15 if builtins.typeOf importedModule == "lambda"
16 then
17 importedModule
18 (transformArgs args)
19 else importedModule;
20 moduleName =
21 if builtins.typeOf module == "lambda"
22 then "<AnonFunction>"
23 else if builtins.typeOf module == "path"
24 then builtins.toString module
25 else builtins.toJSON module;
Skyler Greyf649adf2022-08-26 06:47:44 +010026 in
Skyler Grey252927a2022-10-18 22:18:15 +010027 lib.warnIfNot
28 ((lib.pipe resolvedModule [
29 builtins.attrNames
30 (lib.subtractLists [ "home" "config" "imports" "options" "traces" ])
31 ])
32 == [ ])
33 "Module ${moduleName} had attribute names ${builtins.toJSON (builtins.attrNames resolvedModule)} but only home, config, imports and options are resolved"
34 [
35 {
36 config = lib.recursiveUpdate (resolvedModule.config or { }) {
37 home-manager.users."${args.username}".imports =
38 (resolvedModule.config.home-manager.users."${args.username}".imports or [ ])
39 ++ [ resolvedModule.home or { } ];
40 };
41 imports = resolvedModule.imports or [ ];
42 options = resolvedModule.options or { };
43 }
44 ]
45 ++ (builtins.map
46 (trace:
47 let
48 splitTrace = lib.splitString "." trace;
49 traceHead = builtins.head splitTrace;
50 traceTail = builtins.tail splitTrace;
51 resolvedTrace =
52 (
53 if traceHead == "home"
54 then [ "home-manager" "users" args.username ]
55 else lib.errorIfNot (traceHead == "config") [ ]
56 )
57 ++ traceTail;
58 in
59 { config, ... }: (builtins.seq
60 (
61 lib.pipe resolvedTrace [
62 (lib.foldl
63 ({ value
64 , error
65 ,
66 }: key:
67 if builtins.hasAttr key value
68 then {
69 value = value.${key};
70 inherit error;
71 }
72 else {
73 value = { };
74 error = true;
75 })
76 {
77 value = { };
78 error = false;
79 })
80 (data: lib.warnIf data.error "trace@${moduleName}/${trace} is invalid; the key does not exist" data)
81 ({ value
82 , error
83 ,
84 }: {
85 value = builtins.toJSON value;
86 inherit error;
87 })
88 ({ value
89 , error
90 ,
91 }: {
92 value = "trace@${moduleName}/${trace}: ${value}";
93 inherit error;
94 })
95 ({ value
96 , error
97 ,
98 }:
99 lib.traceIf (!error) value null)
100 ]
101 )
102 { }))
103 (resolvedModule.traces or [ ]));
104in
105{
Skyler Greybcb2cb72022-08-21 07:24:35 +0100106 imports = (
107 if builtins.typeOf modules == "list"
Skyler Greyf649adf2022-08-26 06:47:44 +0100108 then builtins.concatLists (builtins.map resolver modules)
109 else resolver modules
Skyler Greybcb2cb72022-08-21 07:24:35 +0100110 );
111}