{ 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; }