#!/bin/sh dry_run() { [ -n "$DRY_RUN" ]; } usage() { echo "Usage: $(basename $0) [-h] [-f]" echo "" echo " -h print this help and exit" echo " -f modify filesystem rather than dry run" } ############################################################################### # Helper Functions ############################################################################### if [ -t 1 ]; then rst=$(tput sgr0) red=$(tput setaf 1) green=$(tput setaf 2) yellow=$(tput setaf 3) blue=$(tput setaf 4) magenta=$(tput setaf 5) cyan=$(tput setaf 6) else rst='' red='' green='' yellow='' blue='' magenta='' cyan='' fi heading() { printf '%s\n' "${blue}===== $1 ==========${rst}"; } info() { printf '%s ' "$@"; printf '\n'; } ok() { printf '%s ' "${green}OK:${rst}" "$@"; printf '\n'; } warn() { printf '%s ' "${yellow}$@${rst}"; printf '\n'; } error() { printf '%s ' "${red}$@${rst}"; printf '\n'; } is_installed() { command -v nvim >/dev/null 2>&1 } greeting() { dry_run && info "Dry run: no changes will be made to filesytem (use -f to override)." info "Deploying with git user $yellow${GIT_USER:-$DEFAULT_GIT_USER} <${GIT_EMAIL:-$DEFAULT_GIT_EMAIL}>$rst" [ -t 0 ] && { info "Press ENTER to continue (CTRL-C to cancel)..." read k } } # Make sure directory $1 exists. ensure_directory() { if [ -d "$1" ]; then ok "$1/" else warn "creating $1/" dry_run || mkdir -p "$1/" fi } # Make sure file $1 does not exist. remove_file() { if [ ! -f "$1" ]; then ok "$1" else warn "removing $1" dry_run || rm "$1" fi } # Make sure file $1 exists (content is irrelevant). touch_file() { if [ -f "$1" ]; then ok "$1" else warn "creating $1" dry_run || touch "$1" fi } # Remove $1 if it's a broken link to a dotfile script. prune_cmd() { if [ -h "$1" ]; then # it's a symbolic link... target="$(readlink "$1")" case "$target" in "$DOTFILES/bin/"*) # ... pointing into dotfiles bin if [ ! -e "$1" ]; then # target of the link missing warn "removing stale link $1 -> $target" dry_run || rm -f "$1" fi ;; esac fi } # Make sure $2 is a link to $1. link() { target="$(realpath -s "$1")" if [ "$(readlink "$2")" = "$target" ]; then ok "$2" else warn "linking $2 -> $target" dry_run || ln -sf "$target" "$2" fi } # Ensure $1 and $2 contents are equal, updating $1 if needed. equal_content() { if diff "$1" "$2" >/dev/null 2>&1; then ok "$1" else warn "overwriting $1 with $2:" cat "$2" dry_run || cp -f "$2" "$1" fi } ############################################################################### # Configuration Deployments ############################################################################### deploy_alacritty() { heading 'alacritty' ensure_directory "$XDG_CONFIG_HOME/alacritty" link "$DOTFILES/alacritty/alacritty.yml" "$XDG_CONFIG_HOME/alacritty/alacritty.yml" } deploy_bash() { heading 'bash' for f in .bash_logout .profile; do remove_file "$HOME/$f"; done ensure_directory "$XDG_DATA_HOME/bash" # for history ensure_directory "$XDG_DATA_HOME/bash-completion/completions" link "$DOTFILES/bash/bashrc" "${HOME}/.bashrc" link "$DOTFILES/bash/bash_profile" "${HOME}/.bash_profile" } deploy_bin() { heading 'bin' ensure_directory "$HOME/.local/bin" for cmd in $HOME/.local/bin/*; do prune_cmd "$cmd"; done for cmd in "$DOTFILES/bin/"*; do link "$cmd" "$HOME/.local/bin/$(basename "$cmd")" done } deploy_git() { heading 'git' ensure_directory "$XDG_CONFIG_HOME/git" ensure_directory "${HOME}/.local/etc/git" link "$DOTFILES/git/gitconfig" "$XDG_CONFIG_HOME/git/config" link "$DOTFILES/git/gitignore" "$XDG_CONFIG_HOME/git/ignore" temp_git="$(mktemp)" cat >"$temp_git" <