{ config, lib, pkgs, ... }: let cfg = config.services.home-manager.autoUpgrade; homeManagerPackage = config.programs.home-manager.package; autoUpgradeApp = pkgs.writeShellApplication { name = "home-manager-auto-upgrade"; text = if cfg.useFlake then '' set -e if [[ ! -f "$FLAKE_DIR/flake.nix" ]]; then echo "No flake.nix found in $FLAKE_DIR." >&2 exit 1 fi echo "Changing to flake directory $FLAKE_DIR" cd "$FLAKE_DIR" echo "Update flake inputs" nix flake update echo "Upgrade Home Manager" home-manager switch --flake . '' else '' echo "Update Nix's channels" nix-channel --update echo "Upgrade Home Manager" home-manager switch ''; runtimeInputs = with pkgs; [ homeManagerPackage nix ]; }; in { meta.maintainers = [ lib.maintainers.pinage404 ]; options = { services.home-manager.autoUpgrade = { enable = lib.mkEnableOption '' the Home Manager upgrade service that periodically updates your Nix channels before running `home-manager switch`''; frequency = lib.mkOption { type = lib.types.str; example = "weekly"; description = '' The interval at which the Home Manager auto upgrade is run. This value is passed to the systemd timer configuration as the `OnCalendar` option. The format is described in {manpage}`systemd.time(7)`. ''; }; useFlake = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to use 'nix flake update' instead of 'nix-channel --update'."; }; flakeDir = lib.mkOption { type = lib.types.str; default = "${config.xdg.configHome}/home-manager"; defaultText = lib.literalExpression ''"''${config.xdg.configHome}/home-manager"''; example = "/home/user/dotfiles"; description = "The directory of the flake to update."; }; }; }; config = lib.mkIf cfg.enable { assertions = [ (lib.hm.assertions.assertPlatform "services.home-manager.autoUpgrade" pkgs lib.platforms.linux) ]; systemd.user = { timers.home-manager-auto-upgrade = { Unit.Description = "Home Manager upgrade timer"; Install.WantedBy = [ "timers.target" ]; Timer = { OnCalendar = cfg.frequency; Unit = "home-manager-auto-upgrade.service"; Persistent = true; }; }; services.home-manager-auto-upgrade = { Unit.Description = "Home Manager upgrade"; Service = { ExecStart = "${autoUpgradeApp}/bin/home-manager-auto-upgrade"; Environment = lib.mkIf cfg.useFlake [ "FLAKE_DIR=${cfg.flakeDir}" ]; }; }; }; }; }