#!/usr/bin/env bash note() { echo -E "$@" } warn() { echo -E "$@">&2 } die() { warn "$@" exit 1 } dotless() { [[ "${1:0:1}" == "." ]] && REPLY="${1:1}" || REPLY="$1" } backup() { note "backing up $1" mkdir -p "${backup_dir:?backup_dir unset}/$(dirname "$1")" [ -e "$backup_dir/$1" ] && die "backup already exists" mv "$1" "$backup_dir/$1" } hardlink() { if [ -e "$1" ]; then [ "$1" -ef "$2" ] && return [ -h "$1" ] && note "removing symbolic link $1" && rm "$1" if [ -s "$1" ]; then backup "$1" || die "$1 already exists" fi fi ln "$2" "$1" || die "couldn't hardlink $1" } softlink_nix() { if [ -e "$1" ]; then if [ -h "$1" ]; then [ "$(readlink "$1")" == "$2" ] && return note "removing symbolic link $1" rm "$1" else die "$1 already exists and is not a symbolic link" fi fi ln -s "$2" "$1" || die "couldn't symlink $1" } softlink_pseudo() { [ -d "$2" ] || die "$1 is not a directory to softlink" if [ ! -d "$1" ]; then mkdir "$1" || die "couldn't mkdir $1" fi ls -A "$2" | while read -r; do local d1="$1/$REPLY" local d2="$2/$REPLY" if [ -d "$d2" ]; then softlink_pseudo "$d1" "$d2" elif [ -f "$d2" ]; then hardlink "$d1" "$d2" else die "i don't know how to pseudo-symlink $d2" fi done ls -A "$1" | while read -r; do local d1="$1/$REPLY" local d2="$2/$REPLY" if [ -d "$d2" ]; then : elif [ ! "$d1" -ef "$d2" ]; then [ "$d1" == ".vim/.netrwhist" ] && continue [ "$d1" == ".vim/backup" ] && continue [ "$d1" == ".vim/bundle" ] && continue [ "$d1" == ".vim/swp" ] && continue [ "$d1" == ".vim/undo" ] && continue warn "new destination file. consider manually moving it:" warn "$d1" fi done } softlink() { if [ -n "$MSYSTEM" ]; then # MSYS2 does not have nor emulate symbolic links. softlink_pseudo "$@" else softlink_nix "$@" fi } which readlink >/dev/null || exit 1 rc="$(readlink -f "$(dirname "$0")" )" cd "$HOME" PATH="${PATH:?No existing PATH}:$rc/sh" backup_dir="$rc/backup-$(date '+%s')" for f in .bashrc .zshrc .-shrc .streamcrap .ea .vimrc \ .inputrc .Xresources .screenrc; do dotless "$f" r="$rc/home/$REPLY" hardlink "$f" "$r" done for d in sh .vim .mpv; do dotless "$d" r="$rc/$REPLY" softlink "$d" "$r" done grep .bashrc .bash_profile >/dev/null 2>&1 \ || echo -e '\n[[ -f ~/.bashrc ]] && . ~/.bashrc' >> .bash_profile for d in Desktop Documents Downloads Music Pictures Public Templates Video Videos; do [ -d "$d" ] || continue is_empty "$d" && rm -r "$d" || note "skipping unempty $d" done mkdir -p opt/local/bin src work play