nix-config/modules/top/classes/home-manager.nix
2026-04-15 18:26:05 -04:00

112 lines
3 KiB
Nix

{
lib,
inputs,
config,
...
}:
let
inherit (lib)
concatMapAttrs
mapAttrs'
nameValuePair
flatten
unique
;
hmLib = inputs.home-manager.lib;
allRoles = config.dendritic.roles;
allFeatures = config.dendritic.features;
resolveRoles =
let
go =
seen: roleName:
if builtins.elem roleName seen then
throw "Circular dendritic role reference detected: ${
builtins.concatStringsSep " -> " (seen ++ [ roleName ])
}"
else
let
role = allRoles.${roleName} or null;
in
if role == null then
throw "Unknown dendritic role: ${roleName}"
else
[ roleName ] ++ flatten (map (go (seen ++ [ roleName ])) role.roles);
in
roleNames: unique (flatten (map (go [ ]) roleNames));
resolveFeatures =
let
go =
seen: featureName:
if builtins.elem featureName seen then
throw "Circular dendritic feature reference detected: ${
builtins.concatStringsSep " -> " (seen ++ [ featureName ])
}"
else
let
feature = allFeatures.${featureName} or null;
in
if feature == null then
throw "Unknown dendritic feature: ${featureName}"
else
[ featureName ] ++ flatten (map (go (seen ++ [ featureName ])) feature.features);
in
featureNames: unique (flatten (map (go [ ]) featureNames));
mkHomeConfigurations = concatMapAttrs (
username: user:
mapAttrs' (
hostName: home:
let
resolvedRoleNames = resolveRoles home.roles;
roleFeatureNames = flatten (map (roleName: allRoles.${roleName}.features) resolvedRoleNames);
resolvedFeatureNames = resolveFeatures roleFeatureNames;
featureHomeModules = flatten (
map (featureName: allFeatures.${featureName}.homeModules) resolvedFeatureNames
);
in
nameValuePair "${username}@${hostName}" (
hmLib.homeManagerConfiguration {
pkgs = import inputs.nixpkgs {
system = home.system;
};
modules = [
../inventory/current.nix
../inventory/features.nix
../inventory/hosts.nix
../inventory/users.nix
../../aspects/roles.nix
{
dendritic.current = {
inherit hostName;
primaryUser = user.username;
};
}
]
++ user.homeModules
++ featureHomeModules
++ home.extraModules
++ [
{
home.username = user.username;
home.homeDirectory = "/home/${user.username}";
home.stateVersion = home.stateVersion;
}
];
extraSpecialArgs = {
inherit inputs;
};
}
)
) user.homes
) config.dendritic.users;
in
{
config.flake.homeConfigurations = mkHomeConfigurations;
}