{ config, lib, utils, ... }: let inherit (utils) systemdUtils; inherit (systemdUtils.lib) makeUnit generateUnits targetToUnit serviceToUnit sliceToUnit socketToUnit timerToUnit pathToUnit; cfg = config.systemd.user; wantedPaths = lib.unique (lib.flatten (lib.attrValues (lib.mapAttrs (name: conf: (builtins.map (wanted: "${wanted}.wants/${name}") (conf.wantedBy or []))) cfg.units))); requiredPaths = lib.unique (lib.flatten (lib.attrValues (lib.mapAttrs (name: conf: (builtins.map (required: "${required}.requires/${name}") (conf.requiredBy or []))) cfg.units))); in { options = { systemd = { user = { units = lib.mkOption { default = {}; type = systemdUtils.types.units; }; services = lib.mkOption { default = {}; type = systemdUtils.types.services; }; slices = lib.mkOption { default = {}; type = systemdUtils.types.slices; }; paths = lib.mkOption { default = {}; type = systemdUtils.types.paths; }; sockets = lib.mkOption { default = {}; type = systemdUtils.types.sockets; }; targets = lib.mkOption { default = {}; type = systemdUtils.types.targets; }; timers = lib.mkOption { default = {}; type = systemdUtils.types.timers; }; unitsPackage = lib.mkOption { type = lib.types.package; }; }; package = lib.mkOption { default = "systemd"; }; globalEnvironment = lib.mkOption { default = {}; }; }; a.wantedServices = lib.mkOption { type = lib.types.listOf lib.types.str; }; }; config = { systemd.user.units = with lib; mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers; systemd.user.unitsPackage = generateUnits { type = "user"; inherit (cfg) units; upstreamUnits = []; upstreamWants = []; package = "systemd"; packages = []; }; # home.file.".config/systemd/user".source = generateUnits { # type = "user"; # inherit (cfg) units; # }; # home.file = lib.mkMerge [ (lib.mapAttrs' (name: conf: (lib.nameValuePair ".config/systemd/user/${name}" { source = "${cfg.unitsPackage}/${name}"; })) cfg.units) (lib.listToAttrs (builtins.map (path: (lib.nameValuePair ".config/systemd/user/${path}" { source = "${cfg.unitsPackage}/${path}"; }) ) (wantedPaths ++ requiredPaths))) ]; }; }