11.stylix/stylix/testbed/autoload.nix
Matt Sturgeon 1fc2289454
stylix: extract testbed modules to autoload.nix (#1520)
Evaluated the set of testbed modules in a separate file from where we
create the testbed NixOS systems.

The first file (autoload.nix) has no dependency on any of Stylix's flake
inputs. The second file (default.nix) takes the matrix as a parameter,
then imports each module into a NixOS system, and wrapper script.

This will enable a partitioned flake to evaluate the set of testbeds
without needing to fully convert them into NixOS systems with
dependencies on dev-inputs.

Link: https://github.com/nix-community/stylix/pull/1520

Reviewed-by: Flameopathic <64027365+Flameopathic@users.noreply.github.com>
Reviewed-by: awwpotato <awwpotato@voidq.com>
Reviewed-by: NAHO <90870942+trueNAHO@users.noreply.github.com>
2025-06-25 02:13:25 +02:00

118 lines
3.2 KiB
Nix

{
pkgs,
lib,
testbedFieldSeparator ? ":",
}:
let
isEnabled = pkgs.callPackage ./is-enabled.nix { };
# Describes all testbed modules loaded from the modules directory.
# A list of attrsets, each containing: { module, path, name }
testbeds = lib.pipe ../../modules [
builtins.readDir
builtins.attrNames
(builtins.concatMap (
module:
let
testbeds = ../../modules/${module}/testbeds;
files = lib.optionalAttrs (builtins.pathExists testbeds) (
builtins.readDir testbeds
);
in
lib.mapAttrsToList (
testbed: type:
let
path = testbeds + "/${testbed}";
pathStr = toString path;
in
if type != "regular" then
throw "${pathStr} must be regular: ${type}"
else if !lib.hasSuffix ".nix" testbed then
throw "testbed must be a Nix file: ${pathStr}"
else if testbed == ".nix" then
throw "testbed must have a name: ${pathStr}"
else
{
inherit module path;
name = lib.removeSuffix ".nix" testbed;
}
) files
))
];
# Import all the testbed themes
themes = lib.pipe ./themes [
builtins.readDir
(lib.filterAttrs (name: _: lib.strings.hasSuffix ".nix" name))
(builtins.mapAttrs (
name: type:
lib.throwIfNot (type == "regular")
"Unexpected filetype in testbed themes: ${toString ./themes/${name}} is a ${type}."
./themes/${name}
))
(lib.mapAttrs' (name: lib.nameValuePair (lib.strings.removeSuffix ".nix" name)))
];
# Construct a NixOS module for the testbed+theme combination.
#
# If the testbed module is enabled, returns an attrset containing it:
# { «name» = «modele»; }
#
# Returns an empty attrset if the testbed module is not enabled.
# { }
makeTestbedModule =
testbed: themeName: themeModule:
let
joinFields = builtins.concatStringsSep testbedFieldSeparator;
fields =
map
(
field:
lib.throwIf (lib.hasInfix testbedFieldSeparator field)
"testbed field must not contain the '${testbedFieldSeparator}' testbed field separator: ${field}"
field
)
[
"testbed"
testbed.name
themeName
];
name = joinFields fields;
in
lib.optionalAttrs (isEnabled testbed.path) {
${name} = {
# Unique key for de-duplication
key = joinFields [
(toString ./.)
name
];
# Location displayed in errors
_file = name;
# Avoid accidental imports, e.g. in submodules or home-manager
_class = "nixos";
imports = [
testbed.path
themeModule
];
config.system.name = name;
};
};
# Generates a copy of each testbed for each of the imported themes.
# I.e. a testbeds*themes matrix
makeTestbeds = testbed: lib.mapAttrsToList (makeTestbedModule testbed) themes;
in
# Testbeds are merged using lib.attrsets.unionOfDisjoint to throw an error if
# any name collides.
builtins.foldl' lib.attrsets.unionOfDisjoint { } (
builtins.concatMap makeTestbeds testbeds
)