-
Notifications
You must be signed in to change notification settings - Fork 13
/
run_hooks
executable file
·233 lines (199 loc) · 6.01 KB
/
run_hooks
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#autoload
# NOTE! This file not only gets used by zsh, but by
# .shared_env, and so has to work when source'd from
# any sh-compatible shell. Well, any sensible sh.
# The design and implementation of the below code is complex.
# See ConfigHooks.org for details.
# Default to 1, and treat empty as 0. This ensures we have an integer.
: ${DEBUG_LOCAL_HOOKS=1} # Only if not set at all
: ${DEBUG_LOCAL_HOOKS:=0} # Only has an effect if set to empty
process_hook () {
zdot_hook_path="$1"
if ! [ -r "$zdot_hook_path" ]; then
if [ "$DEBUG_LOCAL_HOOKS" -ge 2 ]; then
echo "Couldn't read $zdot_hook_path; skipping." >&2
fi
return 0
fi
if [ -z "$hooks_found" ]; then
hooks_found="$zdot_hook_path"
else
hooks_found="$hooks_found $zdot_hook_path"
fi
case "$zdot_action" in
source)
[ "$DEBUG_LOCAL_HOOKS" -gt 0 ] && sh_load_status "$zdot_hook_path"
source "$zdot_hook_path"
;;
find)
;;
*)
echo "Unrecognised run_hooks action $action; aborting." >&2
return 1
esac
return 0
}
should_ignore () {
dirent="$1"
ignore=
case "$dirent" in
*.dis) ignore=y ;;
*.disable) ignore=y ;;
*.disabled) ignore=y ;;
*~) ignore=y ;;
*.d) ignore=y ;;
*.orig) ignore=y ;;
*.zwc) ignore=y ;;
*.zwc.*) ignore=y ;;
\#*\#) ignore=y ;;
CVS) ignore=y ;;
*/CVS) ignore=y ;;
esac
[ -n "$ignore" ]
}
iterate_hooks () {
if [ $# != 2 ]; then
echo "BUG: iterate_hooks called with wrong # of args: $*" >&2
return 1
fi
zdot_action="$1"
zdot_hook="$2"
# origdir="`pwd`"
if [ -z "$zdot_hook" ]; then
echo "BUG: iterate_hooks called with empty hook name: $*" >&2
return 1
fi
hooks_found=
if [ -z "$ZDOTDIRPATH" ]; then
echo "\$ZDOTDIRPATH not defined; don't know where to search for hooks." >&2
return 1
fi
source "$ZDOTDIR/.zsh/functions/enable_nullglob"
[ -n "$ZSH_VERSION" ] && setopt local_options sh_word_split
for dir in $ZDOTDIRPATH; do
if ! [ -d "$dir" ]; then
if [ -n "$shell_interactive" ]; then
echo "BUG: $dir in \$ZDOTDIRPATH did not exist" >&2
fi
continue
fi
zdot_hook_d="$dir/$zdot_hook"
# Detect obsolete files from run_local_hooks
for zdot_hook_path in ${zdot_hook_d%%.d}.*; do
[ "$zdot_hook_path" = "$zdot_hook_d" ] && continue
if should_ignore "$zdot_hook_path"; then
if [ "$DEBUG_LOCAL_HOOKS" -ge 5 ]; then
echo "# Ignoring obsolete hook $zdot_hook_path"
fi
continue
elif [ "$DEBUG_LOCAL_HOOKS" -ge 2 ]; then
echo "WARNING: found obsolete hook $zdot_hook_path" >&2
fi
done
[ -d "$zdot_hook_d" ] || break
# if ! cd "$zdot_hook_d"; then
# echo "BUG? Couldn't cd to $zdot_hook_d" >&2
# return 1
# fi
hostnick=$(cat $ZDOTDIR/.localhost-nickname)
: ${hostnick:=unknown}
for zdot_hook_path in $zdot_hook_d/*; do
dirent="${zdot_hook_path##*/}"
if [ "$DEBUG_LOCAL_HOOKS" -ge 3 ]; then
echo "# Considering possible hook $zdot_hook_path"
fi
if should_ignore "$dirent"; then
if [ "$DEBUG_LOCAL_HOOKS" -ge 5 ]; then
echo "# Ignoring possible hook $dirent"
fi
continue
fi
# Apply filter for special cases
special=
case "$dirent" in
person-*)
person="${dirent#person-}"
[ "$ZDOTUSER" = "$person" ] || continue
special=y
;;
host-*)
host="${dirent#host-}"
# Be lenient with non-FQDN ambiguity
if [ "${HOSTNAME%%.*}" != "${host}" ] && \
[ "${HOSTNAME}" != "${host%%.*}" ] && \
[ "${hostnick}" != "${host%%.*}" ]
then
[ "$DEBUG_LOCAL_HOOKS" -ge 4 ] && \
echo "# $zdot_hook_path hostname $host does not match \$HOSTNAME $HOSTNAME"
continue
fi
special=y
;;
uid-*)
uid="${dirent#uid-}"
if [ "$uid" = 'OWNER' ]; then
uid=$( stat -c '%U' "$zdot_hook_path" ) # portable?
# uid=$( command ls -l "$zdot_hook_path" | awk '{print $3}' ) # sucks
fi
if [ "$USERNAME" != "$uid" ]; then
[ "$DEBUG_LOCAL_HOOKS" -ge 4 ] && \
echo "# $zdot_hook_path uid $uid does not match \$USERNAME $USERNAME"
continue
fi
special=y
;;
esac
if [ -n "$special" ]; then
[ "$DEBUG_LOCAL_HOOKS" -ge 4 ] && \
echo "# $zdot_hook_path is a special case hook"
if [ -d "$zdot_hook_path" ]; then
for subhook in $zdot_hook_path/*; do
if should_ignore "$subhook"; then
if [ "$DEBUG_LOCAL_HOOKS" -ge 5 ]; then
echo "# Ignoring possible subhook $subhook"
fi
continue
fi
process_hook "$subhook"
done
elif [ -f "$zdot_hook_path" ]; then
echo "WARNING: $zdot_hook_path should be a directory not a file" >&2
process_hook "$zdot_hook_path"
else
echo "WARNING: $zdot_hook_path was not a directory or even a file" >&2
file "$zdot_hook_path" >&2
fi
else
if ! [ -d "$zdot_hook_path" ]; then
process_hook "$zdot_hook_path"
fi
fi
done
done
restore_nullglob
}
run_hooks () {
if [ $# != 1 ]; then
echo "Usage: run_hooks <hookname>" >&2
return 1
fi
if [ "$1" = 'DEFUN' ]; then
# We only want to define the functions above, not do anything.
# This is for the benefit of find_hooks.
return 0
fi
iterate_hooks source "$@"
}
# Ensure we have sh_load_status. It's missing when an X session starts up.
if type sh_load_status >/dev/null 2>&1; then
#if [ -z "$shared_env_loaded" ]; then
:
else
# Catch 22, this would go into infinite recursion:
# . ${zdotdir:-$HOME}/.shared_env
sh_load_status () {
# This should only ever log to .xsession-my-errors anyway
echo "$0: $*"
}
fi
run_hooks "$@"