From 37694e9f5143ff64fdd201f02e37a68e6fc90288 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Tue, 17 Mar 2020 22:27:29 +0100 Subject: [PATCH] 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. --- modules/files.nix | 22 +++++++++++++++++++++- modules/lib/file-type.nix | 12 ++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/files.nix b/modules/files.nix index bd052885..0b87d539 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -43,6 +43,13 @@ in # overwrite an existing file. home.activation.checkLinkTargets = hm.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} @@ -50,12 +57,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" diff --git a/modules/lib/file-type.nix b/modules/lib/file-type.nix index 3096a6d3..f82e9170 100644 --- a/modules/lib/file-type.nix +++ b/modules/lib/file-type.nix @@ -80,6 +80,18 @@ with lib; 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 = {