aboutsummaryrefslogtreecommitdiff
path: root/home-manager/modules/files.nix
diff options
context:
space:
mode:
Diffstat (limited to 'home-manager/modules/files.nix')
-rw-r--r--home-manager/modules/files.nix55
1 files changed, 42 insertions, 13 deletions
diff --git a/home-manager/modules/files.nix b/home-manager/modules/files.nix
index 94b3aa565a8..09ecf715497 100644
--- a/home-manager/modules/files.nix
+++ b/home-manager/modules/files.nix
@@ -39,10 +39,24 @@ in
};
config = {
+ lib.file.mkOutOfStoreSymlink = path:
+ let
+ pathStr = toString path;
+ name = hm.strings.storeFileName (baseNameOf pathStr);
+ in
+ pkgs.runCommandLocal name {} ''ln -s ${escapeShellArg pathStr} $out'';
+
# This verifies that the links we are about to create will not
# 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 +64,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"
@@ -63,10 +90,10 @@ in
errorEcho "Existing file '$backup' would be clobbered by backing up '$targetPath'"
collision=1
else
- warnEcho "Existing file '$targetPath' is in the way, will be moved to '$backup'"
+ warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be moved to '$backup'"
fi
else
- errorEcho "Existing file '$targetPath' is in the way"
+ errorEcho "Existing file '$targetPath' is in the way of '$sourcePath'"
collision=1
fi
fi
@@ -142,7 +169,7 @@ in
if [[ -e "$newGenFiles/$relativePath" ]] ; then
$VERBOSE_ECHO "Checking $targetPath: exists"
elif [[ ! "$(readlink "$targetPath")" == $homeFilePattern ]] ; then
- warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
+ warnEcho "Path '$targetPath' does not link into a Home Manager generation. Skipping delete."
else
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
@@ -197,8 +224,7 @@ in
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum"
- $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
- $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath"
+ $DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else
echo "No change so reusing latest profile generation $oldGenNum"
@@ -231,7 +257,7 @@ in
home-files = pkgs.runCommand
"home-manager-files"
{
- nativeBuildInputs = [ pkgs.xlibs.lndir ];
+ nativeBuildInputs = [ pkgs.xorg.lndir ];
preferLocalBuild = true;
allowSubstitutes = false;
}
@@ -290,12 +316,15 @@ in
}
'' + concatStrings (
mapAttrsToList (n: v: ''
- insertFile "${sourceStorePath v}" \
- "${v.target}" \
- "${if v.executable == null
- then "inherit"
- else builtins.toString v.executable}" \
- "${builtins.toString v.recursive}"
+ insertFile ${
+ escapeShellArgs [
+ (sourceStorePath v)
+ v.target
+ (if v.executable == null
+ then "inherit"
+ else toString v.executable)
+ (toString v.recursive)
+ ]}
'') cfg
));
};