about summary refs log tree commit diff stats
path: root/dots.sh
blob: c312cb13ebe3bc5033ab1ffa6711aaeca35422f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/bin/sh

QUIET=false
NORUN=false
FORCE=false
DIR="$(dirname "$(realpath "$0")")"

main() {
	action=homify
	while getopts hqnfdx OPT
	do
		case "$OPT" in
			(h) usage; exit 0 ;;
			(q) QUIET=true ;;
			(n) NORUN=true ;;
			(f) FORCE=true ;;
			(d) action=dotify ;;
			(x) set -x ;;
			(*) usage; exit 1 ;;
		esac
	done
	shift $((OPTIND - 1))
	"$action" "$@"
}

usage() {
	cat<<EOF
Usage: $0 [-h] [-q] [-n] [-f] [-x] [-d] [FILE] [FIND_ARGS...]
Flags:
 -h	Show this help and exit
 -q	Don't print what's happening
 -n	Just print what would happen
 -f	Force links (ln -f)
 -x	Trace program
 -d	Link from FILE to the dots dir
	(Default: link from FILE to $HOME)
	When linking to $HOME, add a dot at the front of FILE
	When linking to dots, remove the dot from the front of FILE
Parameters:
 FILE	File or directory to link.
	If not given, link all the files in dots.
	If not given along with '-d', ... I don't know what'll happen
 FIND_ARGS
	Extra arguments to pass to find.
EOF
}

log() { $QUIET || echo >&2 "* $@"; }
run() { log "$@"; $NORUN || "$@"; }

mklink() { # mklink SOURCE DEST
	# make hardlinks to DEST from SOURCE -- making directories
	$NORUN || test -d "$(dirname "$2")" || run mkdir -p "$(dirname "$2")"
	if ! test -f "$2"
	then run ln "$1" "$2"
	elif test -f "$2" && "$FORCE"
	then run ln -f "$1" "$2"
	else log "$2 exists: skipping"
	fi
}

getfiles() {
	d="$1"; shift
	find "$d" -type f -a -not -name "$(basename "$0")" "$@"
}

homify() {
	getfiles "$DIR" "$@" |
		while read -r dot
		do mklink "$dot" "$HOME/.${dot#$DIR/}"
		done
}

dotify() {
	getfiles "$@" |
		while read -r file
		do
			lf="${file##$HOME/}" # remove $HOME
			lf="${lf#.}"	   # remove starting dot
			mklink "$file" "$DIR/$lf"
		done
}

main "$@"