Merge pull request 'clan-core/nixos: remove autoloading magic in favour of simple code' (#5476) from fix-a into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5476
This commit is contained in:
hsjobeki
2025-10-12 14:39:17 +00:00
6 changed files with 180 additions and 25 deletions

View File

@@ -19,28 +19,19 @@ let
nixosLib = import (self.inputs.nixpkgs + "/nixos/lib") { }; nixosLib = import (self.inputs.nixpkgs + "/nixos/lib") { };
in in
{ {
imports = imports = filter pathExists [
let ./devshell/flake-module.nix
clanCoreModulesDir = ../nixosModules/clanCore; ./flash/flake-module.nix
getClanCoreTestModules = ./installation/flake-module.nix
let ./update/flake-module.nix
moduleNames = attrNames (builtins.readDir clanCoreModulesDir); ./morph/flake-module.nix
testPaths = map ( ./nixos-documentation/flake-module.nix
moduleName: clanCoreModulesDir + "/${moduleName}/tests/flake-module.nix" ./dont-depend-on-repo-root.nix
) moduleNames; # clan core submodule tests
in ../nixosModules/clanCore/machine-id/tests/flake-module.nix
filter pathExists testPaths; ../nixosModules/clanCore/postgresql/tests/flake-module.nix
in ../nixosModules/clanCore/state-version/tests/flake-module.nix
getClanCoreTestModules ];
++ filter pathExists [
./devshell/flake-module.nix
./flash/flake-module.nix
./installation/flake-module.nix
./update/flake-module.nix
./morph/flake-module.nix
./nixos-documentation/flake-module.nix
./dont-depend-on-repo-root.nix
];
flake.check = genAttrs [ "x86_64-linux" "aarch64-darwin" ] ( flake.check = genAttrs [ "x86_64-linux" "aarch64-darwin" ] (
system: system:
let let

View File

@@ -0,0 +1,51 @@
{ lib }:
let
sanitizePath =
rootPath: path:
let
storePrefix = builtins.unsafeDiscardStringContext ("${rootPath}");
pathStr = lib.removePrefix "/" (
lib.removePrefix storePrefix (builtins.unsafeDiscardStringContext (toString path))
);
in
pathStr;
mkFunctions = rootPath: passthru: virtual_fs: {
# Some functions to override lib functions
pathExists =
path:
let
pathStr = sanitizePath rootPath path;
isPassthru = builtins.any (exclude: (builtins.match exclude pathStr) != null) passthru;
in
if isPassthru then
builtins.pathExists path
else
let
res = virtual_fs ? ${pathStr};
in
lib.trace "pathExists: '${pathStr}' -> '${lib.generators.toPretty { } res}'" res;
readDir =
path:
let
pathStr = sanitizePath rootPath path;
base = (pathStr + "/");
res = lib.mapAttrs' (name: fileInfo: {
name = lib.removePrefix base name;
value = fileInfo.type;
}) (lib.filterAttrs (n: _: lib.hasPrefix base n) virtual_fs);
isPassthru = builtins.any (exclude: (builtins.match exclude pathStr) != null) passthru;
in
if isPassthru then
builtins.readDir path
else
lib.trace "readDir: '${pathStr}' -> '${lib.generators.toPretty { } res}'" res;
};
in
{
virtual_fs,
rootPath,
# Patterns
passthru ? [ ],
}:
mkFunctions rootPath passthru virtual_fs

View File

@@ -36,6 +36,10 @@ lib.fix (
# TODO: Flatten our lib functions like this: # TODO: Flatten our lib functions like this:
resolveModule = clanLib.callLib ./resolve-module { }; resolveModule = clanLib.callLib ./resolve-module { };
fs = {
inherit (builtins) pathExists readDir;
};
}; };
in in
f f

View File

@@ -133,12 +133,12 @@ in
} }
) )
{ {
# TODO: Figure out why this causes infinite recursion # Note: we use clanLib.fs here, so that we can override it in tests
inventory = lib.optionalAttrs (builtins.pathExists "${directory}/machines") ({ inventory = lib.optionalAttrs (clanLib.fs.pathExists "${directory}/machines") ({
imports = lib.mapAttrsToList (name: _t: { imports = lib.mapAttrsToList (name: _t: {
_file = "${directory}/machines/${name}"; _file = "${directory}/machines/${name}";
machines.${name} = { }; machines.${name} = { };
}) ((lib.filterAttrs (_: t: t == "directory") (builtins.readDir "${directory}/machines"))); }) ((lib.filterAttrs (_: t: t == "directory") (clanLib.fs.readDir "${directory}/machines")));
}); });
} }
{ {

108
lib/modules/dir_test.nix Normal file
View File

@@ -0,0 +1,108 @@
{
lib ? import <nixpkgs/lib>,
}:
let
clanLibOrig = (import ./.. { inherit lib; }).__unfix__;
clanLibWithFs =
{ virtual_fs }:
lib.fix (
lib.extends (
final: _:
let
clan-core = {
clanLib = final;
modules.clan.default = lib.modules.importApply ./clan { inherit clan-core; };
# Note: Can add other things to "clan-core"
# ... Not needed for this test
};
in
{
clan = import ../clan {
inherit lib clan-core;
};
# Override clanLib.fs for unit-testing against a virtual filesystem
fs = import ../clanTest/virtual-fs.nix { inherit lib; } {
inherit rootPath virtual_fs;
# Example of a passthru
# passthru = [
# ".*inventory\.json$"
# ];
};
}
) clanLibOrig
);
rootPath = ./.;
in
{
test_autoload_directories =
let
vclan =
(clanLibWithFs {
virtual_fs = {
"machines" = {
type = "directory";
};
"machines/foo-machine" = {
type = "directory";
};
"machines/bar-machine" = {
type = "directory";
};
};
}).clan
{ config.directory = rootPath; };
in
{
inherit vclan;
expr = {
machines = lib.attrNames vclan.config.inventory.machines;
definedInMachinesDir = map (
p: lib.hasInfix "/machines/" p
) vclan.options.inventory.valueMeta.configuration.options.machines.files;
};
expected = {
machines = [
"bar-machine"
"foo-machine"
];
definedInMachinesDir = [
true # /machines/foo-machine
true # /machines/bar-machine
false # <clan-core>/module.nix defines "machines" without members
];
};
};
# Could probably be unified with the previous test
# This is here for the sake to show that 'virtual_fs' is a test parameter
test_files_are_not_machines =
let
vclan =
(clanLibWithFs {
virtual_fs = {
"machines" = {
type = "directory";
};
"machines/foo.nix" = {
type = "file";
};
"machines/bar.nix" = {
type = "file";
};
};
}).clan
{ config.directory = rootPath; };
in
{
inherit vclan;
expr = {
machines = lib.attrNames vclan.config.inventory.machines;
};
expected = {
machines = [ ];
};
};
}

View File

@@ -12,6 +12,7 @@ let
in in
####### #######
{ {
autoloading = import ./dir_test.nix { inherit lib; };
test_missing_self = test_missing_self =
let let
eval = clan { eval = clan {