Feat(clanLib): init types {uniqueDeferredSerializableModule}

This commit is contained in:
Johannes Kirschbauer
2025-05-21 18:11:04 +02:00
parent e2520f6aa8
commit 7dc03f8eee
5 changed files with 97 additions and 0 deletions

View File

@@ -43,6 +43,8 @@ lib.fix (clanLib: {
inventory = clanLib.callLib ./inventory { };
modules = clanLib.callLib ./inventory/frontmatter { };
test = clanLib.callLib ./test { };
# Custom types
types = clanLib.callLib ./types { };
# Plain imports.
introspection = import ./introspection { inherit lib; };

View File

@@ -11,6 +11,7 @@ rec {
./introspection/flake-module.nix
./inventory/flake-module.nix
./jsonschema/flake-module.nix
./types/flake-module.nix
];
flake.clanLib = import ./default.nix {
inherit lib inputs self;

28
lib/types/default.nix Normal file
View File

@@ -0,0 +1,28 @@
{ lib, ... }:
{
uniqueDeferredSerializableModule = lib.fix (
self:
# Essentially the "raw" type, but with a custom name and check
lib.mkOptionType {
name = "deferredModule";
description = "deferred module that has custom check and merge behavior";
descriptionClass = "noun";
# Unfortunately, tryEval doesn't catch JSON errors
check = value: lib.seq (builtins.toJSON value) true;
merge = lib.options.mergeUniqueOption {
message = "------";
merge = loc: defs: {
imports = map (
def: lib.setDefaultModuleLocation "${def.file}, via option ${lib.showOption loc}" def.value
) defs;
};
};
functor = {
inherit (self) name;
type = self;
# Non mergable type
binOp = _a: _b: null;
};
}
);
}

View File

@@ -0,0 +1,25 @@
{ self, inputs, ... }:
{
perSystem =
{ ... }:
let
# Module that contains the tests
# This module adds:
# - legacyPackages.<system>.eval-tests-hello-world
# - checks.<system>.eval-tests-hello-world
test-types-module = (
self.clanLib.test.flakeModules.makeEvalChecks {
module = throw "";
inherit self inputs;
testName = "types";
tests = ./tests.nix;
# Optional arguments passed to the test
testArgs = { };
}
);
in
{
imports = [ test-types-module ];
legacyPackages.xxx = { };
};
}

41
lib/types/tests.nix Normal file
View File

@@ -0,0 +1,41 @@
{ lib, clanLib, ... }:
let
evalSettingsModule =
m:
lib.evalModules {
modules = [
{
options.foo = lib.mkOption {
type = clanLib.types.uniqueDeferredSerializableModule;
};
}
m
];
};
in
{
test_1 =
let
eval = evalSettingsModule {
foo = { };
};
in
{
inherit eval;
expr = eval.config.foo;
expected = {
# Foo has imports
# This can only ever be one module due to the type of foo
imports = [
{
# This is the result of 'setDefaultModuleLocation'
# Which also returns exactly one module
_file = "<unknown-file>, via option foo";
imports = [
{ }
];
}
];
};
};
}