diff options
Diffstat (limited to 'home-manager/modules/files.nix')
-rw-r--r-- | home-manager/modules/files.nix | 55 |
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 )); }; |