lib/introspection: backwards support older nixpkgs version with reduced features

This commit is contained in:
Johannes Kirschbauer
2025-10-02 17:38:46 +02:00
parent 13c2581cbd
commit 149e14e85d
2 changed files with 112 additions and 1 deletions

View File

@@ -164,7 +164,20 @@ let
else
getPrios { options = opt; }
) filteredOptions;
getPriosLegacy = import ./getPriosLegacy.nix { inherit lib; };
wrap =
{
options,
}:
# Test _module.check for valueMeta
# This option should always exist if options comes from a module evaluation
if options._module.check ? valueMeta then
getPrios { inherit options; }
else
getPriosLegacy { inherit options; };
in
{
inherit getPrios;
getPrios = wrap;
}

View File

@@ -0,0 +1,98 @@
{
lib ? import <nixpkgs/lib>,
}:
let
filterOptions = lib.filterAttrs (
name: _:
!builtins.elem name [
"_module"
"_freeformOptions"
]
);
# Use for nixpkgs < 25.11
getPriosLegacy =
{
options,
}:
let
filteredOptions = filterOptions options;
in
lib.mapAttrs (
_: opt:
let
prio = {
__prio = opt.highestPrio;
};
filteredSubOptions = filterOptions (opt.type.getSubOptions opt.loc);
zipDefs = builtins.zipAttrsWith (_: vs: vs);
prioPerValue =
{ type, defs }:
lib.mapAttrs (
attrName: prioSet:
let
# Evaluate the submodule
# Remove once: https://github.com/NixOS/nixpkgs/pull/391544 lands
# This is currently a workaround to get the submodule options
# It also has a certain loss of information, on nested attrsOf, which is rare, but not ideal.
options = filteredSubOptions;
modules = (
[
{
inherit options;
_file = "<artifical submodule>";
}
]
++ map (config: { inherit config; }) defs.${attrName}
);
submoduleEval = lib.evalModules {
inherit modules;
};
in
(lib.optionalAttrs (prioSet ? highestPrio) {
__prio = prioSet.highestPrio;
})
// (
if type.nestedTypes.elemType.name == "submodule" then
getPriosLegacy { options = submoduleEval.options; }
else
# Nested attrsOf
(lib.optionalAttrs
(type.nestedTypes.elemType.name == "attrsOf" || type.nestedTypes.elemType.name == "lazyAttrsOf")
(
prioPerValue {
type = type.nestedTypes.elemType;
defs = zipDefs defs.${attrName};
} prioSet.value
)
)
)
);
submodulePrios =
let
modules = (opt.definitions ++ opt.type.getSubModules);
submoduleEval = lib.evalModules {
inherit modules;
};
in
getPriosLegacy { options = filterOptions submoduleEval.options; };
in
if opt ? type && opt.type.name == "submodule" then
(prio) // submodulePrios
else if opt ? type && (opt.type.name == "attrsOf" || opt.type.name == "lazyAttrsOf") then
prio
// (prioPerValue {
type = opt.type;
defs = zipDefs opt.definitions;
} (lib.modules.mergeAttrDefinitionsWithPrio opt))
else if opt ? type && opt._type == "option" then
prio
else
getPriosLegacy { options = opt; }
) filteredOptions;
in
getPriosLegacy