stylix/mk-target: polish implementation and improve error reporting

Polish the mkTarget implementation to improve error reporting and
simplify future enhancements.

Configuration elements can now recursively resolve to paths.
This commit is contained in:
NAHO 2025-07-19 11:28:34 +02:00
parent 1272e6858e
commit f7b554dea9
No known key found for this signature in database
GPG key ID: BFB5D5E3F4C95185

View file

@ -182,63 +182,75 @@
configElements ? [ ],
enableExample ? null,
extraOptions ? { },
generalConfig ? null,
generalConfig ? { },
imports ? [ ],
}@args:
let
module =
{ config, lib, ... }:
let
cfg = config.stylix.targets.${name};
callModule =
let
areArgumentsEnabled = lib.flip lib.pipe [
builtins.attrValues
(builtins.all (argument: argument.enable or (argument != null)))
];
# Get the list of function de-structured argument names.
functionArgNames =
fn:
lib.pipe fn [
lib.functionArgs
builtins.attrNames
];
getArguments =
function:
lib.genAttrs
(lib.pipe function [
lib.functionArgs
builtins.attrNames
])
(
argument:
if argument == "cfg" then
cfg
getStylixAttrs =
fn:
lib.genAttrs (functionArgNames fn) (
arg:
if arg == "cfg" then
cfg
else if arg == "colors" then
config.lib.stylix.colors
else if argument == "colors" then
config.lib.stylix.colors
else
config.stylix.${argument} or (throw "stylix: mkTarget expected one of ${
lib.concatMapStringsSep ", " (expected: "`${expected}`") (
lib.naturalSort (
[
"cfg"
"colors"
]
++ builtins.attrNames config.stylix
)
)
}, but got: ${argument}")
);
in
safeguard: config':
let
arguments = getArguments config';
in
if builtins.isFunction config' then
if safeguard then
lib.mkIf (areArgumentsEnabled arguments) (config' arguments)
else
config.stylix.${arg}
or (throw "stylix: mkTarget expected one of `cfg`, `colors`, ${
lib.concatMapStringsSep ", " (name: "`${name}`") (
builtins.attrNames config.stylix
)
}, but got: ${arg}")
);
config' arguments
# Call the configuration function with its required Stylix arguments.
callModule = fn: fn (getStylixAttrs fn);
else if builtins.isAttrs config' then
config'
else if builtins.isPath config' then
callModule safeguard (import config')
# Safeguard configuration functions when any of their arguments is
# disabled.
mkConditionalConfig =
c:
if builtins.isFunction c then
let
allAttrsEnabled = lib.pipe c [
getStylixAttrs
builtins.attrValues
# If the attr has no enable option, it is instead disabled when null
(builtins.all (attr: attr.enable or (attr != null)))
];
in
lib.mkIf allAttrsEnabled (callModule c)
else
c;
throw "stylix: mkTarget expected a configuration to be a function, an attribute set, or a path, but got ${builtins.typeOf config'}: ${
lib.generators.toPretty { } config'
}";
cfg = config.stylix.targets.${name};
in
{
imports = imports ++ [
{ options.stylix.targets.${name} = callModule (lib.toFunction extraOptions); }
{ options.stylix.targets.${name} = callModule false extraOptions; }
];
options.stylix.targets.${name}.enable =
@ -257,14 +269,8 @@ let
config = lib.mkIf (config.stylix.enable && cfg.enable) (
lib.mkMerge (
lib.optional (generalConfig != null) (
callModule (
if builtins.isPath generalConfig then import generalConfig else generalConfig
)
)
++ map (c: mkConditionalConfig (if builtins.isPath c then import c else c)) (
lib.toList configElements
)
lib.singleton (callModule false generalConfig)
++ map (callModule true) (lib.toList configElements)
)
);
};