-
Notifications
You must be signed in to change notification settings - Fork 1
/
install.sh
executable file
·168 lines (142 loc) · 4.65 KB
/
install.sh
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/sh
my_tempdir= # Generated later
if echo test | read -s -n1 testvar 2>/dev/null; then
sread() { read -s -n1 "$@"; }
else
sread() { read "$@"; }
fi
_colour_diff_fallback() {
colour_red=$(printf '\033[31m')
colour_green=$(printf '\033[32m')
colour_reset=$(printf '\033[0m')
sed "s/^-/${colour_red}-/;s/^\+/${colour_green}+/;s/$/${colour_reset}/"
}
_colour_diff() {
if command -v delta >/dev/null; then
delta --paging never
elif command -v colordiff >/dev/null; then
colordiff
else
_colour_diff_fallback
fi
}
_install() {
install -pvTDm "$3" -- "$1" "$2"
}
_copy_to_git() {
install -pTm "$3" -- "$2" "$1"
}
render_m4() { ./render-m4 "$1" >"$2"; }
print_hr() {
eval "$(resize 2>/dev/null)"
printf '━%.0s' $(seq "${COLUMNS:-80}")
printf \\n
}
get_mode() {
stat -c%a "$1"
}
get_and_compare_mode() {
path=$1
desired_mode=$2
actual_mode=$(get_mode "$path")
printf %s\\n "$actual_mode"
[ "$actual_mode" = "$desired_mode" ]
}
replace_right_file() {
display_path=$1
awk -v path="$display_path" '
BEGIN { go = 1 }
go && /^\+\+\+ / { $0 = "+++ " path; go = 0 }
{ print }
'
}
safecopy() {
local operation answer path dest_path display_path orig_path readonly
path=$1 dest_path=$2 readonly=false
display_path=$path
[ "${path%.inc.m4}" != "$path" ] && return # Don't copy .inc.m4 files
desired_mode=$(get_mode "$path")
# If the path ends in .m4, render it first
if [ "${path%.m4}" != "$path" ]; then
display_path=${display_path%.m4} # Hide the .m4 from the user :^)
dest_path=${dest_path%.m4} # Install without .m4 too
orig_path=$path
path=$my_tempdir/m4_out # Why not just mktemp? Because it would be more of a pain to clean up.
readonly=true # Can't copy this back to git after it's rendered
if ! render_m4 "$orig_path" "$path"; then
printf >&2 'Failed to render %s\n'
return 1
fi
fi
operation=_install
if [ -r "$dest_path" ]; then
if ! diff=$(diff -U5 -- "$dest_path" "$path") \
|| ! actual_mode=$(get_and_compare_mode "$dest_path" "$desired_mode"); then
print_hr
if [ -n "$diff" ]; then
printf %s\\n "$diff" | replace_right_file "$display_path" | _colour_diff
else
printf 'Permissions differ for %s: %s -> %s\n' "$display_path" "$actual_mode" "$desired_mode"
fi
printf 'You have a different version of %s - if you install, the above changes will be applied.\n' "$display_path"
answer=
while :; do case $answer in
[iI]) operation=_install; break;;
[gG])
if $readonly; then
answer= # Forget we said anything and prompt again
else
operation=_copy_to_git
break
fi
;;
[vV]) operation=vimdiff; break;;
[sS]) return 0;;
[qQ]) exit 0;;
*)
if $readonly; then
echo "What should I do? (I)nstall, (V)imdiff, (S)kip, (Q)uit"
else
echo "What should I do? (I)nstall, Update in (G)it repo, (V)imdiff, (S)kip, (Q)uit"
fi
sread answer
;;
esac; done
else
return 0
fi
fi
"$operation" "$path" "$dest_path" "$desired_mode"
}
recurse() {
local file
for file in "$2"/* "$2"/.*; do
case "$(basename "$file")" in
# Handle globbed ./..
.|..) continue;;
# Handle failed globs (blah/* where * doesn't exist)
*) [ -e "$file" ] || continue;;
esac
if [ -d "$file" ]; then
recurse "$1" "$file"
elif [ -f "$file" ]; then
"$1" "$file"
fi
done
true
}
# Ensure we are in the script's directory
[ "$0" = "${0%/*}" ] || cd -- "${0%/*}"
# Set cleanup traps and then create a temporary working area
cleanup() { rm -rf -- "${my_tempdir:?}"; }
trap cleanup EXIT
trap 'exit 1' INT HUP TERM PIPE # dash doesn't call EXIT traps on interrupt etc.
my_tempdir=$(mktemp -d) || exit
# Start copying scripts and dotfiles over
_copy_loop() { safecopy "$1" "$HOME/$1"; }
recurse _copy_loop bin
_dotfiles_copy_loop() { safecopy "$1" "$HOME/${1#*/}"; }
recurse _dotfiles_copy_loop dotfiles
echo 'As always, make sure you have pulled submodules!'
# Install pomfclip
cd pomfclip && ./install.sh