Activating a class module on an aspect depending on condition #646
|
Is there a clean way to activate a particular class module on an aspect depending on if some condition is met? For example, currently each of my hosts declare the capabilities it provides (e.g. networking, battery, graphics), and feature aspects check that the capabilities they provide are provided by the host within the current resolution in order to selectively activate their class modules: # features/ghostty.nix
# included by user `alice`'s aspect,
# but should only take effect on hosts with graphics
{
den.aspects.features.ghostty = {
homeManager = { host, ... }:
import ../_require_capabilities.nix host [ "graphics" ] {
programs.ghostty.enable = true;
};
};
}# _require_capabilities.nix
host:
requiredCapabilities:
output:
let
areRequiredCapabilitiesMet = ...; # check if required capabilities satisfied on host
in
if areRequiredCapabilitiesMet then
output
else
{}Ideally, I would like to refactor Is there a cleaner way to do this? And maybe turning it into an aspect isn't the right move? (And I know using custom classes as roles is one way to provide similar-ish "capability" functionality, but I don't want to have to keep track of so many new class names with a whole bunch of roles/capabilities. Also, that is limited to one class at a time.) |
Replies: 1 comment 6 replies
|
I've an idea. How about this? { den, lib, ... }: let
# deps host.hasCapability & host.capabilities
capabilityOpts =
{ lib, host, ... }:
{
options = {
hasCapability = lib.mkOption {
type = with lib.types; functionTo bool;
readOnly = true;
default = capability:
builtins.elem capability host.capabilities;
};
capabilities = lib.mkOption {
type = with lib.types; listOf str;
default = [];
};
};
};
in {
den.schema.host.imports = [ capabilityOpts ];
den.hosts.x86_64-linux = {
igloo.capabilites = [ "graphics" ];
iceberg = {};
};
den.aspects.features.ghostty = {
homeManager =
{ host, ... }:
lib.optionalAttrs (host.hasCapability "graphics") {
programs.ghostty.enable = true;
# ....
};
};
# ....
}You might want to refactor hasCapability (string) into hasCapabilities (list of strings) |
I've an idea. How about this?