home-manager: internalize uninstall

This adds a Boolean option `uninstall`. When enabled this option will
reset side-effecting configurations to their "empty" state. The intent
is that this will cause the activation script to remove all managed
files and packages.

Doing it this way should hopefully be more robust than the previous
solution. It also allows a somewhat more convenient uninstall process
when using Flakes; put `uninstall = true` in your existing
configuration and then do a switch.

Also add simple uninstall test in CI test job.
This commit is contained in:
Robert Helgesson 2024-01-06 00:22:27 +01:00
parent 93e804e7f8
commit 7403ed4980
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
7 changed files with 118 additions and 77 deletions

View file

@ -0,0 +1,50 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf mkOption types;
in {
options.uninstall = mkOption {
type = types.bool;
default = false;
description = ''
Whether to set up a minimal configuration that will remove all managed
files and packages.
Use this with extreme care since running the generated activation script
will remove all Home Manager state from your user environment. This
includes removing all your historic Home Manager generations.
'';
};
config = mkIf config.uninstall {
home.packages = lib.mkForce [ ];
home.file = lib.mkForce { };
home.stateVersion = lib.mkForce "23.11";
home.enableNixpkgsReleaseCheck = lib.mkForce false;
manual.manpages.enable = lib.mkForce false;
news.display = lib.mkForce "silent";
home.activation.uninstall =
lib.hm.dag.entryAfter [ "installPackages" "linkGeneration" ] ''
nixProfileRemove home-manager-path
if [[ -e $hmDataPath ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG -r "$hmDataPath"
fi
if [[ -e $hmStatePath ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG -r "$hmStatePath"
fi
if [[ -e $genProfilePath ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG "$genProfilePath"*
fi
if [[ -e $legacyGenGcPath ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG "$legacyGenGcPath"
fi
'';
};
}