lib.values: init getPrio
This function can be used to get the priority of all values within a module
This commit is contained in:
@@ -15,6 +15,7 @@ in
|
|||||||
buildClan = import ./build-clan { inherit lib nixpkgs clan-core; };
|
buildClan = import ./build-clan { inherit lib nixpkgs clan-core; };
|
||||||
facts = import ./facts.nix { inherit lib; };
|
facts = import ./facts.nix { inherit lib; };
|
||||||
inventory = import ./inventory { inherit lib clan-core; };
|
inventory = import ./inventory { inherit lib clan-core; };
|
||||||
|
values = import ./values { inherit lib; };
|
||||||
jsonschema = import ./jsonschema { inherit lib; };
|
jsonschema = import ./jsonschema { inherit lib; };
|
||||||
modules = import ./frontmatter {
|
modules = import ./frontmatter {
|
||||||
inherit lib;
|
inherit lib;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
./jsonschema/flake-module.nix
|
./jsonschema/flake-module.nix
|
||||||
./inventory/flake-module.nix
|
./inventory/flake-module.nix
|
||||||
./build-clan/flake-module.nix
|
./build-clan/flake-module.nix
|
||||||
|
./values/flake-module.nix
|
||||||
];
|
];
|
||||||
flake.lib = import ./default.nix {
|
flake.lib = import ./default.nix {
|
||||||
inherit lib inputs;
|
inherit lib inputs;
|
||||||
|
|||||||
90
lib/values/default.nix
Normal file
90
lib/values/default.nix
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
lib ? import <nixpkgs/lib>,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
filterOptions = lib.filterAttrs (
|
||||||
|
name: _:
|
||||||
|
!builtins.elem name [
|
||||||
|
"_module"
|
||||||
|
"_freeformOptions"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
getPrios =
|
||||||
|
{
|
||||||
|
options,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
filteredOptions = filterOptions options;
|
||||||
|
in
|
||||||
|
lib.mapAttrs (
|
||||||
|
_: opt:
|
||||||
|
let
|
||||||
|
prio = {
|
||||||
|
__prio = opt.highestPrio;
|
||||||
|
};
|
||||||
|
subOptions = opt.type.getSubOptions opt.loc;
|
||||||
|
|
||||||
|
attrDefinitions = (lib.modules.mergeAttrDefinitionsWithPrio opt);
|
||||||
|
zipDefs = builtins.zipAttrsWith (_ns: vs: vs);
|
||||||
|
defs = zipDefs opt.definitions;
|
||||||
|
|
||||||
|
prioPerValue =
|
||||||
|
{ type, defs }:
|
||||||
|
lib.mapAttrs (
|
||||||
|
attrName: prioSet:
|
||||||
|
let
|
||||||
|
# Evaluate the submodule
|
||||||
|
options = filterOptions subOptions;
|
||||||
|
modules = (
|
||||||
|
[
|
||||||
|
{ inherit options; }
|
||||||
|
]
|
||||||
|
++ map (config: { inherit config; }) defs.${attrName}
|
||||||
|
);
|
||||||
|
submoduleEval = lib.evalModules {
|
||||||
|
inherit modules;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
(lib.optionalAttrs (prioSet ? highestPrio) {
|
||||||
|
__prio = prioSet.highestPrio;
|
||||||
|
# inherit defs options;
|
||||||
|
})
|
||||||
|
// (
|
||||||
|
if type.nestedTypes.elemType.name == "submodule" then
|
||||||
|
getPrios { options = submoduleEval.options; }
|
||||||
|
else
|
||||||
|
# Nested attrsOf
|
||||||
|
(lib.optionalAttrs (type.nestedTypes.elemType.name == "attrsOf") (
|
||||||
|
prioPerValue {
|
||||||
|
type = type.nestedTypes.elemType;
|
||||||
|
defs = zipDefs defs.${attrName};
|
||||||
|
} prioSet.value
|
||||||
|
))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
attributePrios = prioPerValue {
|
||||||
|
type = opt.type;
|
||||||
|
inherit defs;
|
||||||
|
} attrDefinitions;
|
||||||
|
in
|
||||||
|
if opt ? type && opt.type.name == "submodule" then
|
||||||
|
prio // (getPrios { options = subOptions; })
|
||||||
|
else if opt ? type && opt.type.name == "attrsOf" then
|
||||||
|
# prio // attributePrios
|
||||||
|
# else if
|
||||||
|
# opt ? type && opt.type.name == "attrsOf" && opt.type.nestedTypes.elemType.name == "attrsOf"
|
||||||
|
# then
|
||||||
|
# prio // attributePrios
|
||||||
|
# else if opt ? type && opt.type.name == "attrsOf" then
|
||||||
|
prio // attributePrios
|
||||||
|
else if opt ? type && opt._type == "option" then
|
||||||
|
prio
|
||||||
|
else
|
||||||
|
getPrios { options = opt; }
|
||||||
|
) filteredOptions;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit getPrios;
|
||||||
|
}
|
||||||
24
lib/values/flake-module.nix
Normal file
24
lib/values/flake-module.nix
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{ self, inputs, ... }:
|
||||||
|
let
|
||||||
|
inputOverrides = builtins.concatStringsSep " " (
|
||||||
|
builtins.map (input: " --override-input ${input} ${inputs.${input}}") (builtins.attrNames inputs)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, system, ... }:
|
||||||
|
{
|
||||||
|
checks = {
|
||||||
|
lib-values-eval = pkgs.runCommand "tests" { nativeBuildInputs = [ pkgs.nix-unit ]; } ''
|
||||||
|
export HOME="$(realpath .)"
|
||||||
|
|
||||||
|
nix-unit --eval-store "$HOME" \
|
||||||
|
--extra-experimental-features flakes \
|
||||||
|
${inputOverrides} \
|
||||||
|
--flake ${self}#legacyPackages.${system}.evalTests-inventory
|
||||||
|
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
211
lib/values/test.nix
Normal file
211
lib/values/test.nix
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
# tests for the nixos options to jsonschema converter
|
||||||
|
# run these tests via `nix-unit ./test.nix`
|
||||||
|
{
|
||||||
|
lib ? (import <nixpkgs> { }).lib,
|
||||||
|
slib ? (import ./. { inherit lib; }),
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
eval =
|
||||||
|
modules:
|
||||||
|
let
|
||||||
|
evaledConfig = lib.evalModules {
|
||||||
|
inherit modules;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
evaledConfig;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
test_default = {
|
||||||
|
expr = slib.getPrios {
|
||||||
|
options =
|
||||||
|
(eval [
|
||||||
|
{
|
||||||
|
options.foo.bar = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Test Description";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]).options;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
foo.bar = {
|
||||||
|
__prio = 1500;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
test_no_default = {
|
||||||
|
expr = slib.getPrios {
|
||||||
|
options =
|
||||||
|
(eval [
|
||||||
|
{
|
||||||
|
options.foo.bar = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]).options;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
foo.bar = {
|
||||||
|
__prio = 9999;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test_submodule = {
|
||||||
|
expr = slib.getPrios {
|
||||||
|
options =
|
||||||
|
(eval [
|
||||||
|
{
|
||||||
|
options.foo = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
bar = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]).options;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
foo = {
|
||||||
|
# Prio of the submodule itself
|
||||||
|
__prio = 9999;
|
||||||
|
|
||||||
|
# Prio of the bar option within the submodule
|
||||||
|
bar.__prio = 9999;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO(@hsjobeki): Cover this edge case
|
||||||
|
# test_freeform =
|
||||||
|
# let
|
||||||
|
# evaluated = (
|
||||||
|
# eval [
|
||||||
|
# {
|
||||||
|
# freeformType = with lib.types; attrsOf (int);
|
||||||
|
# options = {
|
||||||
|
# foo = lib.mkOption {
|
||||||
|
# type = lib.types.int;
|
||||||
|
# default = 0;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# }
|
||||||
|
# {
|
||||||
|
# bar = lib.mkForce 123;
|
||||||
|
# baz = 1;
|
||||||
|
# }
|
||||||
|
# {
|
||||||
|
# bar = 10;
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# );
|
||||||
|
# in
|
||||||
|
# {
|
||||||
|
# inherit evaluated;
|
||||||
|
# expr = slib.getPrios {
|
||||||
|
# options = evaluated.options;
|
||||||
|
# };
|
||||||
|
# expected = {
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
test_attrsOf_submodule =
|
||||||
|
let
|
||||||
|
evaluated = eval [
|
||||||
|
{
|
||||||
|
options.foo = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
bar = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
config.foo = {
|
||||||
|
"nested" = {
|
||||||
|
"bar" = 2; # <- 100 prio ?
|
||||||
|
};
|
||||||
|
"other" = {
|
||||||
|
"bar" = lib.mkForce 2; # <- 50 prio ?
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
expr = slib.getPrios { options = evaluated.options; };
|
||||||
|
expected = {
|
||||||
|
foo.__prio = 100;
|
||||||
|
|
||||||
|
foo.nested.__prio = 100;
|
||||||
|
foo.other.__prio = 100;
|
||||||
|
|
||||||
|
foo.nested.bar.__prio = 100;
|
||||||
|
foo.other.bar.__prio = 50;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
test_attrsOf_attrsOf_submodule =
|
||||||
|
let
|
||||||
|
evaluated = eval [
|
||||||
|
{
|
||||||
|
options.foo = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
bar = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
config.foo = {
|
||||||
|
a.b = {
|
||||||
|
bar = 1;
|
||||||
|
};
|
||||||
|
a.c = {
|
||||||
|
bar = 1;
|
||||||
|
};
|
||||||
|
x.y = {
|
||||||
|
bar = 1;
|
||||||
|
};
|
||||||
|
x.z = {
|
||||||
|
bar = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit evaluated;
|
||||||
|
expr = slib.getPrios { options = evaluated.options; };
|
||||||
|
expected = {
|
||||||
|
foo.__prio = 100;
|
||||||
|
|
||||||
|
# Sub A
|
||||||
|
foo.a.__prio = 100;
|
||||||
|
# a.b doesnt have a prio
|
||||||
|
# a.c doesnt have a prio
|
||||||
|
foo.a.b.bar.__prio = 100;
|
||||||
|
foo.a.c.bar.__prio = 100;
|
||||||
|
|
||||||
|
# Sub X
|
||||||
|
foo.x.__prio = 100;
|
||||||
|
# x.y doesnt have a prio
|
||||||
|
# x.z doesnt have a prio
|
||||||
|
foo.x.y.bar.__prio = 100;
|
||||||
|
foo.x.z.bar.__prio = 100;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user