files: add force flag

Enabling this flag for a `home.file` entry causes the target to be
unconditionally overwritten. The option is not visible in
documentation for now and shouldn't be relied on for general use.

(cherry picked from commit 37694e9f51)
This commit is contained in:
Robert Helgesson 2020-03-17 22:27:29 +01:00
parent 0d1ca254d0
commit 57f3b72d3a
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
2 changed files with 33 additions and 1 deletions

View file

@ -45,6 +45,13 @@ in
# overwrite an existing file.
home.activation.checkLinkTargets = dag.entryBefore ["writeBoundary"] (
let
# Paths that should be forcibly overwritten by Home Manager.
# Caveat emptor!
forcedPaths =
concatMapStringsSep " " (p: ''"$HOME/${p}"'')
(mapAttrsToList (n: v: v.target)
(filterAttrs (n: v: v.force) cfg));
check = pkgs.writeText "check" ''
. ${./lib-bash/color-echo.sh}
@ -52,12 +59,25 @@ in
# considered part of a Home Manager generation.
homeFilePattern="$(readlink -e "${builtins.storeDir}")/*-home-manager-files/*"
forcedPaths=(${forcedPaths})
newGenFiles="$1"
shift
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \
forced=""
for forcedPath in "''${forcedPaths[@]}"; do
if [[ $targetPath == $forcedPath* ]]; then
forced="yeah"
break
fi
done
if [[ -n $forced ]]; then
$VERBOSE_ECHO "Skipping collision check for $targetPath"
elif [[ -e "$targetPath" \
&& ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"

View file

@ -86,6 +86,18 @@ in
into place.
'';
};
force = mkOption {
type = types.bool;
default = false;
visible = false;
description = ''
Whether the target path should be unconditionally replaced
by the managed file source. Warning, this will silently
delete the target regardless of whether it is a file or
link.
'';
};
};
config = {