Skip to content

Instantly share code, notes, and snippets.

@clktmr
Created July 27, 2022 19:11
Show Gist options
  • Save clktmr/7343895cc0dcc5a80a6c3d39d22ca0d9 to your computer and use it in GitHub Desktop.
Save clktmr/7343895cc0dcc5a80a6c3d39d22ca0d9 to your computer and use it in GitHub Desktop.
#!/bin/sh -e
# DOTFILES Files that will be installed by this script.
# DOTFILES_DEPS Files that should be installed via the systems package
# manager prior to installing the dotfiles. Currently only
# dnf is supported.
# DOTFILES_DESTDIR Directory to install the dotfiles to.
# Default: $HOME
# DOTFILES_CONFDIR Directory where this script will store stuff like backups
# and a list of previously installed files.
# Default: $DOTFILES_DESTDIR/.dotfiles
DOTFILES_DESTDIR=${DOTFILES_DESTDIR:-"$HOME"}
DOTFILES_CONFDIR=${DOTFILES_CONFDIR:-"$DOTFILES_DESTDIR/.dotfiles"}
CONFFILE="$DOTFILES_CONFDIR/dotfiles"
BACKUPDIR="$DOTFILES_CONFDIR/backup"
if [ -n "$DOTFILES_DEPS" ]; then
sudo dnf install $DOTFILES_DEPS
fi
mkdir -p "$DOTFILES_CONFDIR" "$BACKUPDIR"
touch "$CONFFILE"
echo "Installing dotfiles (I=install, B=backup, R=rollback, D=delete)"
echo "$DOTFILES" |
while IFS= read -r f; do
dest="$DOTFILES_DESTDIR/$f"
# skip empty lines
if [ -z "$f" ]; then
continue
fi
if [ ! -e "$PWD/$f" ]; then
>&2 echo "$0: cannot install '$PWD/$f': No such file or directory."
exit 1
fi
# create a backup if file already exists
if [ -f "$dest" ] || [ -d "$dest" ]; then
if [ -h "$dest" ] && [ "$(readlink "$dest" == "$PWD/$f")" ]; then
continue
else
mkdir -p "$(dirname "$BACKUPDIR/$f")"
mv "$dest" "$BACKUPDIR/$f"
echo "B $f"
fi
fi
# install file by creating symlink to it
mkdir -p "$(dirname "$dest")"
if ln -s "$PWD/$f" "$dest"; then
echo "$f" >> "$CONFFILE"
echo "I $f"
else
echo "ERROR: Linking of $f failed" 1>&2
if [ -f "$BACKUPDIR/$f" ]; then
mv "$BACKUPDIR/$f" "$dest"
echo "R $f"
fi
fi
done
# remove files that shouldn't be installed
touch "$CONFFILE.swp"
while IFS= read -r f; do
dest="$DOTFILES_DESTDIR/$f"
if ! echo "$DOTFILES" | grep -q "^\s*$f\s*$"; then
if [ -h "$dest" ] && [ "$(readlink "$dest" == "$PWD/$f")" ]; then
rm "$dest"
echo "D $f"
fi
if [ -f "$BACKUPDIR/$f" ]; then
mv "$BACKUPDIR/$f" "$dest"
echo "R $f"
fi
else
echo "$f" >> "$CONFFILE.swp"
fi
done < "$CONFFILE"
mv "$CONFFILE.swp" "$CONFFILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment