-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.nix
135 lines (122 loc) · 3.27 KB
/
utils.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
{lib, ...}: let
inherit
(builtins)
attrNames
isAttrs
readDir
listToAttrs
attrValues
;
inherit
(lib)
filterAttrs
hasSuffix
hasPrefix
mapAttrs'
mapAttrsToList
nameValuePair
removeSuffix
;
# mapFilterAttrs ::
# (name -> value -> bool )
# (name -> value -> { name = any; value = any; })
# attrs
mapFilterAttrs = sieve: f: attrs: filterAttrs sieve (mapAttrs' f attrs);
# Generate an attribute set by mapping a function over a list of values.
genAttrs' = values: f: listToAttrs (map f values);
importProfilesDir = path: dir: content:
mapAttrsToList (n: v: importProfilesRec (path ++ [n]) "${dir}/${n}") content;
importProfilesRec = path: dir: let
content = readDir dir;
in
if content ? "default.nix"
then wrap true path (import "${dir}")
else importProfilesDir path dir content;
importProfiles = dir: lib.flatten (importProfilesRec [] dir);
wrap = main: path: profile: {
lib,
pkgs,
config,
nixosConfig,
...
} @ args: let
prf =
if builtins.isAttrs profile
then profile
else profile args;
cfg = builtins.removeAttrs prf ["imports"];
prepImport = imp:
if builtins.isAttrs imp
then imp
else import imp;
imports =
if prf ? "imports"
then builtins.map (p: wrap false path (prepImport p)) prf.imports
# then prf.imports
else [];
in
{
inherit imports;
config = lib.mkIf (lib.attrByPath path {enable = false;} config.profiles).enable cfg;
}
// (
if !main
then {}
else {
options.profiles = lib.setAttrByPath path {
enable = lib.mkEnableOption "Enable profile ${lib.concatMapStrings "/" path}";
};
}
);
in {
inherit mapFilterAttrs genAttrs' importProfiles;
recImport = {
dir,
_import ? base: import "${dir}/${base}.nix",
}:
mapFilterAttrs
(_: v: v != null)
(n: v:
if n != "default.nix" && hasSuffix ".nix" n && v == "regular"
then let name = removeSuffix ".nix" n; in nameValuePair name (_import name)
else nameValuePair "" null)
(readDir dir);
recImportDir = {
dir,
_import ? path: import path,
}:
mapFilterAttrs
(_: v: v == "directory")
(n: v: nameValuePair n (_import "${dir}/${n}"))
(readDir dir);
# Convert a list to file paths to attribute set
# that has the filenames stripped of nix extension as keys
# and imported content of the file as value.
pathsToImportedAttrs = paths:
genAttrs' paths (path: {
name = removeSuffix ".nix" (baseNameOf path);
value = import path;
});
# List files in directory that are not hidden
readVisible = dir:
filterAttrs
(name: _: !(hasPrefix "." name))
(readDir dir);
# x -> (x -> string -> v -> { acc : x; value: v }) -> attrset -> attrset
foldOverAttrs = init: op: attrs:
(builtins.foldl'
(acc: attr: let
nattr = op acc.acc attr.name attr.value;
in {
acc = nattr.acc;
value = acc.value // {"${attr.name}" = nattr.value;};
})
{
acc = init;
value = {};
}
(mapAttrsToList nameValuePair attrs))
.value;
# Returns a list of name value pairs for an attrset
attrNameValuePairs = mapAttrsToList nameValuePair;
}