files: backup file collisions

When a configuration file would be written to an existing file, rather
than failing switch (and having the user have to move or delete those
files), move the files automatically to a new path.

Closes #585
This commit is contained in:
Judson 2019-04-17 12:15:38 -07:00 committed by Robert Helgesson
parent 5b50eb18fc
commit f82246171b
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
3 changed files with 38 additions and 4 deletions

View file

@ -416,6 +416,7 @@ function doHelp() {
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
echo " expression in the configuration file."
echo " -I PATH Add a path to the Nix expression search path."
echo " -b EXT Move existing files to new path rather than fail."
echo " -v Verbose output"
echo " -n Do a dry run, only prints what actions would be taken"
echo " -h Print this help"
@ -460,7 +461,7 @@ for arg in "$@"; do
fi
done
while getopts 2f:I:A:vnh opt; do
while getopts 2f:I:A:b:vnh opt; do
case $opt in
2)
USE_NIX2_COMMAND=1
@ -474,6 +475,9 @@ while getopts 2f:I:A:vnh opt; do
A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
;;
b)
export HOME_MANAGER_BACKUP_EXT="$OPTARG"
;;
v)
export VERBOSE=1
;;

View file

@ -59,13 +59,23 @@ in
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \
&& ! "$(readlink "$targetPath")" == ${homeFilePattern} ]] ; then
errorEcho "Existing file '$targetPath' is in the way"
collision=1
if [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
if [[ -e "$backup" ]]; then
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'"
fi
else
errorEcho "Existing file '$targetPath' is in the way"
collision=1
fi
fi
done
if [[ -v collision ]] ; then
errorEcho "Please move the above files and try again"
errorEcho "Please move the above files and try again or use -b <ext> to move automatically."
exit 1
fi
'';
@ -111,6 +121,10 @@ in
for sourcePath in "$@" ; do
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" && ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
$DRY_RUN_CMD mv $VERBOSE_ARG "$targetPath" "$backup" || errorEcho "Moving '$targetPath' failed!"
fi
$DRY_RUN_CMD mkdir -p $VERBOSE_ARG "$(dirname "$targetPath")"
$DRY_RUN_CMD ln -nsf $VERBOSE_ARG "$sourcePath" "$targetPath"
done

View file

@ -1106,6 +1106,22 @@ in
A new module is available: 'programs.gpg'.
'';
}
{
time = "2019-06-09T12:19:18+00:00";
message = ''
Collisions between unmanaged and managed files can now be
automatically resolved by moving the target file to a new
path instead of failing the switch operation. To enable
this, use the new '-b' command line argument. For example,
home-manager -b bck switch
where 'bck' is the suffix to give the moved file. In this
case a colliding file 'foo.conf' will be moved to
'foo.conf.bck'.
'';
}
];
};
}