home-manager-auto-upgrade: state-version gate preSwitchCommands

Migrate the preSwitchCommands default to
lib.hm.deprecations.mkStateVersionOptionDefault instead of using a
null sentinel.

Keep the legacy flake update behavior for older state versions and add
tests for the explicit, legacy, and current flake paths.
This commit is contained in:
Austin Horstman
2026-04-22 19:20:38 -05:00
parent 2706309aeb
commit 667b3c4732
5 changed files with 94 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
{
config,
lib,
options,
pkgs,
...
}:
@@ -10,26 +11,25 @@ let
homeManagerPackage = config.programs.home-manager.package;
preSwitchCommandsStateVersion = lib.hm.deprecations.mkStateVersionOptionDefault {
inherit (config.home) stateVersion;
inherit config options;
since = "26.05";
optionPath = [
"services"
"home-manager"
"autoUpgrade"
"preSwitchCommands"
];
legacy.value = [ "nix flake update" ];
current.value = [ ];
deferWarningToConfig = true;
shouldWarn = { optionUsesDefaultPriority, ... }: cfg.useFlake && optionUsesDefaultPriority;
};
hmExtraArgs = lib.escapeShellArgs cfg.flags;
legacyPreSwitchCommands = lib.warn ''
services.home-manager.autoUpgrade:
Implicit `nix flake update` before `home-manager switch` is deprecated.
Please set `services.home-manager.autoUpgrade.preSwitchCommands`
explicitly.
'' [ "nix flake update" ];
# null = legacy behavior
# [] = run nothing
preSwitchCommands =
if cfg.useFlake && cfg.preSwitchCommands == null then
legacyPreSwitchCommands
else if cfg.preSwitchCommands == null then
[ ]
else
cfg.preSwitchCommands;
hasPreSwitchCommands = preSwitchCommands != [ ];
hasPreSwitchCommands = cfg.preSwitchCommands != [ ];
preSwitchScript = lib.optionalString hasPreSwitchCommands (
lib.concatStringsSep "\n" (
@@ -37,7 +37,7 @@ let
''echo "Running pre-switch commands"''
"set -o xtrace"
]
++ preSwitchCommands
++ cfg.preSwitchCommands
)
);
@@ -139,8 +139,16 @@ in
};
preSwitchCommands = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
type = lib.types.listOf lib.types.str;
default = [ ];
defaultText = lib.literalExpression ''
if lib.versionAtLeast config.home.stateVersion "26.05"
|| !config.services.home-manager.autoUpgrade.useFlake
then
[ ]
else
[ "nix flake update" ]
'';
example = lib.literalExpression ''
[
"''${pkgs.gitMinimal}/bin/git pull"
@@ -149,19 +157,22 @@ in
'';
description = ''
Shell commands executed before `home-manager switch`.
- null: use legacy behavior (deprecated)
- []: run no pre-switch commands
'';
};
};
};
config = lib.mkIf cfg.enable {
warnings = lib.optional preSwitchCommandsStateVersion.shouldWarn preSwitchCommandsStateVersion.warning;
assertions = [
(lib.hm.assertions.assertPlatform "services.home-manager.autoUpgrade" pkgs lib.platforms.linux)
];
services.home-manager.autoUpgrade.preSwitchCommands = lib.mkIf cfg.useFlake (
lib.mkOptionDefault preSwitchCommandsStateVersion.effectiveDefault
);
systemd.user = {
timers.home-manager-auto-upgrade = {
Unit.Description = "Home Manager upgrade timer";

View File

@@ -0,0 +1,19 @@
{
home.stateVersion = "26.05";
services.home-manager.autoUpgrade = {
enable = true;
frequency = "daily";
useFlake = true;
flakeDir = "/tmp/my-flake";
};
nmt.script = ''
serviceFile="home-files/.config/systemd/user/home-manager-auto-upgrade.service"
assertFileExists "$serviceFile"
assertFileRegex "$serviceFile" "FLAKE_DIR=/tmp/my-flake"
scriptPath=$(grep -oP 'ExecStart=\K.+' "$TESTED/$serviceFile")
assertFileNotRegex "$scriptPath" "nix flake update"
'';
}

View File

@@ -2,5 +2,7 @@
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
home-manager-auto-upgrade-basic-configuration = ./basic-configuration.nix;
home-manager-auto-upgrade-current-flake-configuration = ./current-flake-configuration.nix;
home-manager-auto-upgrade-deprecated-flake-configuration = ./deprecated-flake-configuration.nix;
home-manager-auto-upgrade-flake-configuration = ./flake-configuration.nix;
}

View File

@@ -0,0 +1,36 @@
{
home.stateVersion = "25.11";
services.home-manager.autoUpgrade = {
enable = true;
frequency = "daily";
useFlake = true;
flakeDir = "/tmp/my-flake";
};
test.asserts.warnings.expected = [
''
The default value of `services.home-manager.autoUpgrade.preSwitchCommands` has changed from `[
"nix flake update"
]` to `[ ]`.
You are currently using the legacy default (`[
"nix flake update"
]`) because `home.stateVersion` is less than "26.05".
To silence this warning and keep legacy behavior, set:
services.home-manager.autoUpgrade.preSwitchCommands = [
"nix flake update"
];
To adopt the new default behavior, set:
services.home-manager.autoUpgrade.preSwitchCommands = [ ];
''
];
nmt.script = ''
serviceFile="home-files/.config/systemd/user/home-manager-auto-upgrade.service"
assertFileExists "$serviceFile"
assertFileRegex "$serviceFile" "FLAKE_DIR=/tmp/my-flake"
scriptPath=$(grep -oP 'ExecStart=\K.+' "$TESTED/$serviceFile")
assertFileRegex "$scriptPath" "nix flake update"
'';
}

View File

@@ -1,4 +1,6 @@
{
home.stateVersion = "26.05";
services.home-manager.autoUpgrade = {
enable = true;
frequency = "daily";