lib/introspect: recurse for nested attrsOf
This commit is contained in:
@@ -10,6 +10,46 @@ let
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pushPositions = map (
|
||||||
|
def:
|
||||||
|
lib.mapAttrs (_n: v: {
|
||||||
|
inherit (def) file;
|
||||||
|
value = v;
|
||||||
|
}) def.value
|
||||||
|
);
|
||||||
|
|
||||||
|
unwrapNullOr =
|
||||||
|
type:
|
||||||
|
let
|
||||||
|
typeName = type.name or null;
|
||||||
|
in
|
||||||
|
if typeName == "nullOr" then type.nestedTypes.name or null else typeName;
|
||||||
|
|
||||||
|
mergeAttrs =
|
||||||
|
{ type, definitionsWithLocations }:
|
||||||
|
let
|
||||||
|
# Vendored merge from lib.types.attrsOf
|
||||||
|
# Because we still cannot access highest prio for the individual attrs yet.
|
||||||
|
elemType = type.nestedTypes.elemType;
|
||||||
|
mergedAttrs = lib.zipAttrsWith (name: defs: lib.modules.mergeDefinitions ([ name ]) elemType defs) (
|
||||||
|
pushPositions definitionsWithLocations
|
||||||
|
);
|
||||||
|
headType = unwrapNullOr elemType;
|
||||||
|
nullable = elemType.name or null == "nullOr";
|
||||||
|
total = elemType.name or null == "submodule";
|
||||||
|
in
|
||||||
|
lib.mapAttrs (_name: merged: {
|
||||||
|
__this = {
|
||||||
|
prio = merged.defsFinal'.highestPrio;
|
||||||
|
files = map (def: def.file) merged.defsFinal'.values;
|
||||||
|
inherit
|
||||||
|
headType
|
||||||
|
nullable
|
||||||
|
total
|
||||||
|
;
|
||||||
|
};
|
||||||
|
}) mergedAttrs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Takes a set of options as returned by `configuration`
|
Takes a set of options as returned by `configuration`
|
||||||
|
|
||||||
@@ -45,19 +85,15 @@ let
|
|||||||
lib.mapAttrs (
|
lib.mapAttrs (
|
||||||
_: opt:
|
_: opt:
|
||||||
let
|
let
|
||||||
headType =
|
headType = unwrapNullOr opt.type;
|
||||||
let
|
|
||||||
typeName = opt.type.name or null;
|
|
||||||
in
|
|
||||||
if typeName == "nullOr" then opt.type.nestedTypes.name or null else typeName;
|
|
||||||
nullable = opt.type.name or null == "nullOr";
|
nullable = opt.type.name or null == "nullOr";
|
||||||
|
total = opt.type.name or null == "submodule";
|
||||||
|
|
||||||
definitionInfo = {
|
definitionInfo = {
|
||||||
__this = {
|
__this = {
|
||||||
prio = opt.highestPrio or null;
|
prio = opt.highestPrio or null;
|
||||||
files = opt.files or [ ];
|
files = opt.files or [ ];
|
||||||
inherit headType nullable;
|
inherit headType nullable total;
|
||||||
total = opt.type.name or null == "submodule";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,18 +107,34 @@ let
|
|||||||
/**
|
/**
|
||||||
Maps attrsOf and lazyAttrsOf
|
Maps attrsOf and lazyAttrsOf
|
||||||
*/
|
*/
|
||||||
handleAttrsOf = attrs: lib.mapAttrs (_: handleMeta) attrs;
|
handleAttrsOf =
|
||||||
|
type: defs: attrs:
|
||||||
|
lib.mapAttrs (
|
||||||
|
name: meta:
|
||||||
|
(mergeAttrs {
|
||||||
|
inherit type;
|
||||||
|
definitionsWithLocations = defs;
|
||||||
|
}).${name}
|
||||||
|
// handleMeta {
|
||||||
|
inherit meta;
|
||||||
|
definitionsWithLocations =
|
||||||
|
(builtins.zipAttrsWith (_name: values: values) (pushPositions defs)).${name};
|
||||||
|
}
|
||||||
|
) attrs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Maps attrsOf and lazyAttrsOf
|
Maps attrsOf and lazyAttrsOf
|
||||||
*/
|
*/
|
||||||
handleListOf = list: { __list = lib.map handleMeta list; };
|
handleListOf = list: { __list = lib.map handleMeta { meta = list; }; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Unwraps the valueMeta of an option based on its type
|
Unwraps the valueMeta of an option based on its type
|
||||||
*/
|
*/
|
||||||
handleMeta =
|
handleMeta =
|
||||||
meta:
|
{
|
||||||
|
meta,
|
||||||
|
definitionsWithLocations ? [ ],
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
hasType = meta ? _internal.type;
|
hasType = meta ? _internal.type;
|
||||||
type = meta._internal.type;
|
type = meta._internal.type;
|
||||||
@@ -93,7 +145,7 @@ let
|
|||||||
# TODO: handle types
|
# TODO: handle types
|
||||||
getPrios { options = filterOptions meta.configuration.options; }
|
getPrios { options = filterOptions meta.configuration.options; }
|
||||||
else if type.name == "attrsOf" || type.name == "lazyAttrsOf" then
|
else if type.name == "attrsOf" || type.name == "lazyAttrsOf" then
|
||||||
handleAttrsOf meta.attrs
|
handleAttrsOf meta._internal.type definitionsWithLocations meta.attrs
|
||||||
# TODO: Add index support in nixpkgs first
|
# TODO: Add index support in nixpkgs first
|
||||||
# else if type.name == "listOf" then
|
# else if type.name == "listOf" then
|
||||||
# handleListOf meta.list
|
# handleListOf meta.list
|
||||||
@@ -103,7 +155,7 @@ let
|
|||||||
if opt ? type && opt.type.name == "submodule" then
|
if opt ? type && opt.type.name == "submodule" then
|
||||||
(definitionInfo) // submodulePrios
|
(definitionInfo) // submodulePrios
|
||||||
else if opt ? type && (opt.type.name == "attrsOf" || opt.type.name == "lazyAttrsOf") then
|
else if opt ? type && (opt.type.name == "attrsOf" || opt.type.name == "lazyAttrsOf") then
|
||||||
definitionInfo // (handleAttrsOf opt.valueMeta.attrs)
|
definitionInfo // (handleAttrsOf opt.type opt.definitionsWithLocations opt.valueMeta.attrs)
|
||||||
# TODO: Add index support in nixpkgs, otherwise we cannot
|
# TODO: Add index support in nixpkgs, otherwise we cannot
|
||||||
else if opt ? type && (opt.type.name == "listOf") then
|
else if opt ? type && (opt.type.name == "listOf") then
|
||||||
definitionInfo // (handleListOf opt.valueMeta.list)
|
definitionInfo // (handleListOf opt.valueMeta.list)
|
||||||
|
|||||||
@@ -314,12 +314,17 @@ in
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
config.foo.nested = lib.mkForce {
|
||||||
|
# <- 50 prio
|
||||||
|
"bar" = 2;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
config.foo = {
|
config.foo = {
|
||||||
"nested" = {
|
"other" = lib.mkForce {
|
||||||
"bar" = 2; # <- 100 prio ?
|
"bar" = 2; # <- 50 prio
|
||||||
};
|
|
||||||
"other" = {
|
|
||||||
"bar" = lib.mkForce 2; # <- 50 prio ?
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -330,11 +335,19 @@ in
|
|||||||
expected = {
|
expected = {
|
||||||
foo = {
|
foo = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [
|
||||||
|
"<unknown-file>"
|
||||||
|
"<unknown-file>"
|
||||||
|
];
|
||||||
prio = 100;
|
prio = 100;
|
||||||
total = false;
|
total = false;
|
||||||
};
|
};
|
||||||
nested = {
|
nested = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 50;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
@@ -344,10 +357,15 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
other = {
|
other = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 50;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
prio = 50;
|
prio = 100;
|
||||||
total = false;
|
total = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -401,7 +419,17 @@ in
|
|||||||
total = false;
|
total = false;
|
||||||
};
|
};
|
||||||
a = {
|
a = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = false;
|
||||||
|
};
|
||||||
b = {
|
b = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
@@ -411,6 +439,11 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
c = {
|
c = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
@@ -421,7 +454,17 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
x = {
|
x = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = false;
|
||||||
|
};
|
||||||
y = {
|
y = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
@@ -431,6 +474,11 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
z = {
|
z = {
|
||||||
|
__this = {
|
||||||
|
files = [ "<unknown-file>" ];
|
||||||
|
prio = 100;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
bar = {
|
bar = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
@@ -443,7 +491,6 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
test_attrsOf_submodule_default =
|
test_attrsOf_submodule_default =
|
||||||
let
|
let
|
||||||
evaluated = eval [
|
evaluated = eval [
|
||||||
@@ -496,6 +543,14 @@ in
|
|||||||
total = false;
|
total = false;
|
||||||
};
|
};
|
||||||
jon = {
|
jon = {
|
||||||
|
__this = {
|
||||||
|
files = [
|
||||||
|
"<unknown-file>"
|
||||||
|
"inventory.json"
|
||||||
|
];
|
||||||
|
prio = 100;
|
||||||
|
total = true;
|
||||||
|
};
|
||||||
fludl = {
|
fludl = {
|
||||||
__this = {
|
__this = {
|
||||||
files = [ "<unknown-file>" ];
|
files = [ "<unknown-file>" ];
|
||||||
|
|||||||
Reference in New Issue
Block a user