From: Ian Jackson Date: Wed, 9 Dec 2015 00:24:52 +0000 (+0000) Subject: makelinks script seems to work X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=ian-dotfiles.git;a=commitdiff_plain;h=4cc053b8edfcb949f583c4383243a283e36a61b0 makelinks script seems to work --- 4cc053b8edfcb949f583c4383243a283e36a61b0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e75ca3f --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +# + +install: + infra/makelinks setup + +import: + infra/makelinks import + +.PHONY: install diff --git a/infra/makelinks b/infra/makelinks new file mode 100755 index 0000000..0fd38dc --- /dev/null +++ b/infra/makelinks @@ -0,0 +1,109 @@ +#!/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|import|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.clean) ;; +*) badusage ;; +esac + +mode=$1; shift + +dots=$( find dot -type f -name '[0-9a-zA-Z]*[0-9a-zA-Z]' ) + +basepath=$(pwd) +basepath=${basepath#$HOME/} + +estatus=0 + +show () { + printf "%s\n" "$1" +} + +good () { + if [ $mode = list ]; then + show "good: $dot: $1" + fi +} + +bad () { + estatus=16 + show "bad: $dot: $1" >&2 +} + +needs () { + if [ $mode = $1 ]; then + act=$real_act + else + show "needs $1: $prhome: $2" + act=: + fi +} + +log_only () { + echo "x $*" +} + +with_log () { + log_only "$@" + "$@" +} + +for dot in $dots; do + underhome=".${dot#dot/}" + inhome="$HOME/$underhome" + prhome="~/$underhome" + if [ "$inhome" -ef "$dot" ]; then + good "already symlinked here" + elif [ -h "$inhome" ]; then + bad "wrong symlink target" + elif ! [ -e "$inhome" ]; then + needs setup "absent here" + $act ln -s "$basepath/$dot" "$inhome" + elif [ -f "$inhome" ] && cmp -s "$dot" "$inhome"; then + needs setup "identical here but not yet symlinked" + $act rm -f "$inhome"~ + $act ln -s "$basepath/$dot" "$inhome"~ + $act mv -f "$inhome"~ "$inhome" + else + needs import "modified here" + $act rm -f "$dot"~ + $act cp "$inhome" "$dot"~ + $act mv -f "$dot"~ "$dot" + fi +done + +brokens=$( + cd $HOME + find -L .[0-9a-zA-Z]* -xdev -type l -lname "$basepath/dot/*" +) +for underhome in $brokens; do + inhome="$HOME/$underhome" + prhome="~/$underhome" + needs clean "symlink to removed file in dot/" + $act rm -f "$inhome" +done