{ name, lib, config, host, ... }: let inherit (lib.modules) mkIf ; inherit (lib.options) mkOption mkEnableOption literalExpression ; inherit (lib.types) mkOptionType ; t = lib.types; inherit (import ./lib.nix { inherit lib; }) recUpdateFoldl ; pkgs = host.pkgs; /** Either a list of strings, or a dotted string that will be split. */ convenientAttrPath = t.coercedTo t.str (lib.splitString ".") (t.listOf t.str); executablePathInStore = mkOptionType { name = "exepath"; description = "executable path in the Nix store"; descriptionClass = "noun"; merge = lib.mergeEqualOption; functor = lib.defaultFunctor "exepath"; check = x: if lib.isDerivation x then ( x.meta.mainProgram or null != null ) else ( lib.pathInStore.check x ); }; in { options = { enable = mkEnableOption "dynamicism for '${name}'"; source-options = mkOption { type = t.listOf convenientAttrPath; description = "A list of attrpaths of the NixOS option the dynamicism for '${name}' uses"; example = literalExpression '' [ [ "services" "gotosocial" "settings" ] "services.nginx.settings" ] ''; }; systemd-services-updated = mkOption { type = t.listOf t.str; description = '' A list of systemd unit names (including the suffix, e.g. `.service`) that need to be updated. ''; example = literalExpression '' [ "gotosocial.service" ] ''; default = lib.attrNames config.unitDropins; }; finalSettings = mkOption { type = t.attrsOf t.raw; internal = true; default = recUpdateFoldl (optPath: lib.setAttrByPath optPath (lib.getAttrFromPath optPath host.config) ) config.source-options; }; configFile = mkOption { type = t.pathInStore; internal = true; }; unitDropins = mkOption { type = t.attrsOf t.package; internal = true; }; activate = mkOption { type = executablePathInStore; internal = true; }; }; config = mkIf config.enable { activate = pkgs.writeShellApplication { name = "dynamicism-for-${name}-activate"; runtimeInputs = [ pkgs.systemd ]; text = let doEdits = config.unitDropins |> lib.mapAttrsToList (service: dropin: '' cat "${dropin}" | systemctl edit "${service}" --runtime --drop=dynix-${dropin.name} --stdin '') |> lib.concatStringsSep "\n"; doReloads = config.unitDropins |> lib.mapAttrsToList (service: _: '' systemctl reload-or-restart "${service}" '') |> lib.concatStringsSep "\n"; in '' ${doEdits} ${doReloads} ''; }; }; }