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 ? [ ], configElements ? [ ],
enableExample ? null, enableExample ? null,
extraOptions ? { }, extraOptions ? { },
generalConfig ? null, generalConfig ? { },
imports ? [ ], imports ? [ ],
}@args: }@args:
let let
module = module =
{ config, lib, ... }: { config, lib, ... }:
let 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. getArguments =
functionArgNames = function:
fn: lib.genAttrs
lib.pipe fn [ (lib.pipe function [
lib.functionArgs lib.functionArgs
builtins.attrNames builtins.attrNames
]; ])
(
argument:
if argument == "cfg" then
cfg
getStylixAttrs = else if argument == "colors" then
fn: config.lib.stylix.colors
lib.genAttrs (functionArgNames fn) (
arg: else
if arg == "cfg" then config.stylix.${argument} or (throw "stylix: mkTarget expected one of ${
cfg lib.concatMapStringsSep ", " (expected: "`${expected}`") (
else if arg == "colors" then lib.naturalSort (
config.lib.stylix.colors [
"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 else
config.stylix.${arg} config' arguments
or (throw "stylix: mkTarget expected one of `cfg`, `colors`, ${
lib.concatMapStringsSep ", " (name: "`${name}`") (
builtins.attrNames config.stylix
)
}, but got: ${arg}")
);
# Call the configuration function with its required Stylix arguments. else if builtins.isAttrs config' then
callModule = fn: fn (getStylixAttrs fn); 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 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 in
{ {
imports = imports ++ [ imports = imports ++ [
{ options.stylix.targets.${name} = callModule (lib.toFunction extraOptions); } { options.stylix.targets.${name} = callModule false extraOptions; }
]; ];
options.stylix.targets.${name}.enable = options.stylix.targets.${name}.enable =
@ -257,14 +269,8 @@ let
config = lib.mkIf (config.stylix.enable && cfg.enable) ( config = lib.mkIf (config.stylix.enable && cfg.enable) (
lib.mkMerge ( lib.mkMerge (
lib.optional (generalConfig != null) ( lib.singleton (callModule false generalConfig)
callModule ( ++ map (callModule true) (lib.toList configElements)
if builtins.isPath generalConfig then import generalConfig else generalConfig
)
)
++ map (c: mkConditionalConfig (if builtins.isPath c then import c else c)) (
lib.toList configElements
)
) )
); );
}; };