-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.nix
More file actions
129 lines (121 loc) · 3.35 KB
/
utils.nix
File metadata and controls
129 lines (121 loc) · 3.35 KB
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
{ lib, ... }:
rec {
# addOverrides wraps the values of a configuration (attribute set) with
# a call to mkOverride.
# i.e., it transforms the leaf nodes of the attrset tree
# from `<some_value>` to `mkOverride <priority> <some_value>`.
#
# ```
#
# p1 = {
# "a" = 1;
# "b" = {
# "c" = 2;
# }
# }
#
# p2 = addOverrides 100 p1
#
# # value of p2:
# {
# "a" = mkOverride 100 1;
# "b" = {
# "c" = mkOverride 100 2;
# };
# }
#
#
# ```
#
# We can also specify specific priorities for value, instead of using
# `priority` for all the values. See usage of `_priority`:
#
# ```
# p3 = {
# "d" = 1;
# "e" = {
# _value = 2;
# _priority = 50;
# }
# }
#
# p4 = addOverrides 100 p1
#
# # value of p4:
# {
# "d" = mkOverride 100 1;
# "e" = mkOverride 50 2;
# }
#
# ```
addOverrides =
nullPriority: nonNullPriority: cfg:
lib.mapAttrs (
k: v:
if builtins.isAttrs v then
# If the value is an attribute set, check for _value and _priority before recursing
if builtins.hasAttr "_value" v && builtins.hasAttr "_priority" v then
# If _value and _priority are present, apply mkOverride with _priority and _value.
lib.mkOverride v._priority v._value
else
# Otherwise, recurse deeper into the attribute set
addOverrides nullPriority nonNullPriority v
else
# If it's a simple value (no attribute set), apply mkOverride at `priority` level
if v == null then
lib.mkOverride nullPriority v
else
lib.mkOverride nonNullPriority v
) cfg;
# Note:
# Set null to relatively low priority of 1000 (same as mkDefault)
mkPresetWithNulls = priority: cfg: addOverrides 1000 priority cfg;
# Inteneded to ttake in cfg that doesn't have nulls.
mkPreset =
priority: cfg:
lib.mapAttrs (
k: v:
if builtins.isAttrs v then
# If the value is an attribute set, check for _value and _priority before recursing
if builtins.hasAttr "_value" v && builtins.hasAttr "_priority" v then
# If _value and _priority are present, apply mkOverride with _priority and _value.
lib.mkOverride v._priority v._value
else
# Otherwise, recurse deeper into the attribute set
mkPreset priority v
else
lib.mkOverride priority v
) cfg;
removeNullsAndEmptySets =
attrs:
lib.filterAttrs (_: v: v != null && (!lib.isAttrs v || v != { })) (
lib.mapAttrs (_: v: if lib.isAttrs v then removeNullsAndEmptySets v else v) attrs
);
# Takes in an typical options set from a module, and creates a duplicate
# of the options, with addition of making it nullable.
makeNullableOptionsRecursive =
opts:
let
isOption = v: lib.isAttrs v && (v._type or null) == "option";
isNullableType = type: type.name == "nullOr";
makeNullableOption =
opt:
let
newType = if isNullableType opt.type then opt.type else lib.types.nullOr opt.type;
in
opt
// {
type = newType;
default = null;
};
in
lib.mapAttrs (
_name: val:
if isOption val then
makeNullableOption val
else if lib.isAttrs val then
makeNullableOptionsRecursive val
else
val
) opts;
}