dotfiles/install.sh

166 lines
4 KiB
Bash
Executable file

#!/bin/sh
set -e
DOTFILES="$(dirname "$(realpath "$0")")"
TARGET="$HOME"
# shellcheck disable=SC1091 # don't complain about following config.local
[ -r "$DOTFILES/config.local" ] && . "$DOTFILES/config.local"
GIT_USER="${GIT_USER:-Fernando Schauenburg}"
GIT_EMAIL="${GIT_EMAIL:-dev@schauenburg.me}"
main() {
IS_DRY_RUN=yes
while getopts 'fht:' opt; do case "$opt" in
f) unset IS_DRY_RUN;;
t) TARGET="$OPTARG";;
h) usage; exit 0;;
*) usage; exit 1;;
esac done
check_dependencies
greeting
make_dirs
stow_home
link_config
git_user_config
}
check_dependencies() {
for cmd in stow readlink; do
if ! command -v "$cmd" >/dev/null 2>&1; then
error "Dependency \`$cmd\` not found."
exit 1
fi
done
}
greeting() {
dry_run && {
warn "Performing dry run (use -f to actually make changes)."
warn
}
info "Deploying dotfiles:"
info " Source: $cyan$DOTFILES$rst"
info " Target: $cyan$TARGET$rst"
info " Git user: $green$GIT_USER <$GIT_EMAIL>$rst"
if [ -t 0 ] && [ -t 1 ]; then
info
info "Press ENTER to continue (CTRL-C to cancel)..."
read -r
fi
}
make_dirs() {
heading 'create auxiliary directories'
while read -r item; do
dir="$TARGET/$item"
if [ ! -d "$dir" ]; then
echo "${yellow}MKDIR:$rst $dir"
dry_run || mkdir -p "$dir"
fi
done <<EOF
.local/share/less/
.local/share/python/
.local/share/nvim/shada/
.local/share/zsh/
.local/etc/git/
EOF
}
link_config() {
heading 'link .config directory'
link="$TARGET/.config"
dotfiles_config="$DOTFILES/config"
backup="$TARGET/old_dot_config"
if [ "$(readlink "$link")" != "$dotfiles_config" ]; then
if [ -d "$link" ]; then
echo "${red}WARNING:$rst moving existing '$link' to '$backup'"
dry_run || mv "$link" "$backup"
fi
echo "${yellow}LINK:$rst $link $blue=>$rst $dotfiles_config"
dry_run || ln -s "$dotfiles_config" "$link"
fi
}
stow_home() {
heading 'stow home directory'
stow -v${IS_DRY_RUN:+n} --no-folding -d "$DOTFILES" -t "$TARGET" home 2>&1 \
| sed -E \
-e "s/^(WARNING:)/$red\1$rst/" \
-e "s/^([^:]+:)/$yellow\1$rst/" \
-e "s/=>/$blue=>$rst/"
}
git_user_config() {
heading 'git user configuration'
config_file="$TARGET/.local/etc/git/config.user"
temp_git="$(mktemp)"
cat >"$temp_git" <<EOF
# *************************************
# * DO NOT EDIT THIS FILE *
# *************************************
#
# This file was generated by the bootstrap script and any changes will be
# overwritten the next time it is run. For local settings, use this instead:
#
# ~/.local/etc/git/config
#
EOF
git config -f "$temp_git" user.name "${GIT_USER}"
git config -f "$temp_git" user.email "${GIT_EMAIL}"
if ! diff "$config_file" "$temp_git" >/dev/null 2>&1; then
if [ -f "$config_file" ]; then action=OVERWRITE; else action=CREATE; fi
echo "$yellow$action:$rst $config_file with contents of $temp_git:"
echo "$cyan"
cat "$temp_git"
echo "$rst"
dry_run || cp -f "$temp_git" "$config_file"
fi
}
###############################################################################
# Helper Functions
###############################################################################
if [ -t 1 ]; then
rst="$(printf '\033[0m')"
red="$(printf '\033[31m')"
green="$(printf '\033[32m')"
yellow="$(printf '\033[33m')"
blue="$(printf '\033[34m')"
# magenta="$(printf '\033[35m')"
cyan="$(printf '\033[36m')"
else
rst=''
red=''
green=''
yellow=''
blue=''
# magenta=''
cyan=''
fi
dry_run() { [ -n "$IS_DRY_RUN" ]; }
usage() {
echo "Usage: $(basename "$0") [-h] [-f] [-t <target>]"
echo ""
echo " -h print this help and exit"
echo " -f modify filesystem rather than dry run"
echo " -t set <target> directory (default: \$HOME)"
}
heading() { echo "${blue}===== $1 ==========${rst}"; }
info() { echo "$*"; }
warn() { echo "${yellow}$*${rst}"; }
error() { echo "${red}$*${rst}"; }
main "$@"