#!/bin/bash # # To start tracking a file, # cp ~/.screenrc dot/screenrc # # To sort out symlinks when things are clean # infra/makelinks install set -e -o posix -o pipefail badusage () { echo >&2 "usage: $0 [-n|-v] list|setup|dirimport|dirmove|clean" exit 18 } real_act='' while true; do if [ $# = 0 ]; then break; fi case "$1" in -n) real_act=log_only ;; -v) real_act=with_log ;; -*) badusage ;; *) break ;; esac shift done case "$#.$1" in 1.list|1.setup|1.import|1.dirimport|1.clean) ;; *) badusage ;; esac mode=$1; shift basepath=$(pwd) basepath=${basepath#$HOME/} estatus=0 show () { printf "%s\n" "$1" } good () { if [ $mode = list ]; then show "good: $prhome: $1" fi } bad () { estatus=16 show "bad: $prhome: $1" >&2 } needs () { if [ $mode = $1 ]; then act=$real_act show "DOING $1: $prhome ($2)" else show "needs $1: $prhome: $2" act=: fi } log_only () { echo "x $*" } with_log () { log_only "$@" "$@" } process_object () { inhome="$HOME/$underhome" prhome="~/$underhome" linktarget="$basepath/$ours" chompy="$underhome" while true; do case "$chompy" in *?/?*) linktarget="../$linktarget" chompy="${chompy%/*}" ;; *) break ;; esac done if [ "$inhome" -ef "$ours" ]; then good "already symlinked here" elif [ -h "$inhome" ]; then bad "wrong symlink target" elif ! [ -e "$inhome" ]; then needs setup "absent here" $act ln -s "$linktarget" "$inhome" elif [ -f "$inhome" ] && [ -f "$ours" ]; then if cmp -s "$ours" "$inhome"; then needs setup "identical in this ~ but not yet symlinked" $act rm -f "$inhome"~ $act ln -s "$linktarget" "$inhome"~ $act mv -f "$inhome"~ "$inhome" else needs import "modified here" $act rm -f "$ours"~ $act cp "$inhome" "$ours"~ $act mv -f "$ours"~ "$ours" fi elif [ -d "$inhome" ] && [ -d "$ours" ]; then needs dirimport "directory in this ~, not yet symlinked" $act mv "$ours" "$ours~" $act ln -s "$linktarget" "$inhome"~ $act mv "$inhome" "$ours" $act mv "$inhome~" "$inhome" $act rm -rf "$ours~" else bad "mismatched file types" fi } dots=$( find dot -mindepth 1 -maxdepth 1 -name '[0-9a-zA-Z]*[0-9a-zA-Z]' ) for ours in $dots; do underhome=".${ours#dot/}" process_object done nondots=$( find home -mindepth 1 -maxdepth 1 -name '[0-9a-zA-Z]*[0-9a-zA-Z]' ) for ours in $nondots; do underhome="${ours#home/}" process_object done exec 3