-
Notifications
You must be signed in to change notification settings - Fork 122
/
deploy-git-hook
executable file
·187 lines (161 loc) · 5.48 KB
/
deploy-git-hook
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
#!/bin/bash
usage() {
cat <<-EOF
usage: ${0} -d /path/to/git/repository [-a] [-c] [-r] [-u]
-h this help screen
-d path install the hooks to the specified path
-a deploy pre-commit and pre-receive hooks
-c deploy only the pre-commit hook
-r deploy only the pre-receive hook
-u deploy only the post-update hook
-g enable to install in Git Lab repo custom_hooks
-l enable to install in Gitolite 3.6+ repo-specific hooks
-b enable to install in Stash/BitBucket Server [pre/post]-receive.d
returns status code of 0 for success, otherwise, failure
examples:
1) to install pre-commit and pre-receive the hooks to foo git repo:
${0} -d /path/to/foo -a
2) to install only the pre-commit hook to bar git repo:
${0} -d /path/to/bar -c
3) to install only the pre-commit and pre-receive hook to foobar git repo:
${0} -d /path/to/foobar -c -r
EOF
}
while getopts ":d:abcghlru" opt; do
case $opt in
a)
INST_COMMIT=1
INST_RECEIVE=1
;;
b)
BITBUCKET_REPO=1
;;
c)
INST_COMMIT=1
;;
d)
GIT_REPO="$OPTARG"
;;
g)
GITLAB_REPO=1
;;
h)
usage
exit -1
;;
l)
GITOLITE_REPO=1
;;
r)
INST_RECEIVE=1
;;
u)
INST_UPDATE=1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
;;
esac
done
# We need at least one hook to deploy
if [[ -z "${INST_COMMIT}" \
&& -z "${INST_RECEIVE}" \
&& -z "${INST_UPDATE}" ]]; then
echo "Error: You must specify at least one hook to deploy" >&2
usage
exit -2
fi
# We need to have a git repository specified
if [ -z "${GIT_REPO}" ]; then
echo "Error: No repository specified" >&2
usage
exit -3
fi
# Validate the provided repository is a gitolite repository
if [ "${GITOLITE_REPO}" = "1" ]; then
if [ ! -f "${GIT_REPO}/conf/gitolite.conf" ]; then
echo "Error: Not a gitolite admin repository" >&2
exit -7
fi
fi
# Check if the repo specified is a submodule
if [ -f "${GIT_REPO}/.git" ]; then
SUBMODULE_REPO=$(cat "${GIT_REPO}/.git" | grep 'gitdir' | awk '{print $2}')
GIT_REPO="$(cd "${GIT_REPO}" ; cd "${SUBMODULE_REPO}" ; pwd)"
elif [ "${BITBUCKET_REPO}" = "1" ]; then
GIT_REPO="${GIT_REPO}"
elif [ -f "${GIT_REPO}/hooks" ]; then
# This is for bare repos
GIT_REPO="${GIT_REPO}"
else
GIT_REPO="${GIT_REPO}/.git"
fi
GIT_REPO=$(cd "${GIT_REPO}" ; pwd)
# Make sure the repo specified is valid, submodule or normal
if [[ -n "${SUBMODULE_REPO}" && ! -d "${GIT_REPO}" ]]; then
echo "Error: Submodule not a valid repository" >&2
exit -3
elif [[ -z "${SUBMODULE_REPO}" && ! -d "${GIT_REPO}" ]]; then
echo "Error: Not a valid repository" >&2
exit -3
fi
# Cleanup the hooks directory so it works properly
HOOKS_DIR=$(dirname "${0}")
HOOKS_DIR=$(cd "${HOOKS_DIR}" ; pwd)
# Check if it's Git Lab, needs to go into custom_hooks
if [ "${GITLAB_REPO}" = "1" ]; then
REAL_HOOKS_DIR="custom_hooks"
# Check if it's Gitolite, needs repo-specific hook directory
elif [ "${GITOLITE_REPO}" = "1" ]; then
REAL_HOOKS_DIR="../local/hooks/repo-specific"
else
REAL_HOOKS_DIR="hooks"
fi
# Make sure the hooks directory exists -- mainly for Git Lab and Gitolite
if [ ! -d "${GIT_REPO}/${REAL_HOOKS_DIR}" ]; then
mkdir -p "${GIT_REPO}/${REAL_HOOKS_DIR}"
fi
# Install the hooks!
if [ "${GITOLITE_REPO}" = "1" ]; then
if [ "${INST_COMMIT}" = "1" ]; then
echo "Error: pre-commit hooks outside of Gitolite's scope, use non-gitolite arguments to local repo" >&2
exit -8
fi
# Do real copies instead of symlinks in order to not require submodules
# Change naming on files to be more descriptive for gitolite configuration and prevent possible naming collision
if [ "${INST_RECEIVE}" = "1" ]; then
cp -f "${HOOKS_DIR}/pre-receive" "${GIT_REPO}/${REAL_HOOKS_DIR}/puppet-git-hooks.pre-receive" \
&& cp -rf "${HOOKS_DIR}/commit_hooks" "${GIT_REPO}/${REAL_HOOKS_DIR}/" \
&& echo "pre-receive hook deployed successfully" \
|| ( echo "pre-receive hook failed to deploy to gitolite repo" >&2 ; exit -9 )
fi
if [ "${INST_UPDATE}" = "1" ]; then
cp -f "${HOOKS_DIR}/post-update" "${GIT_REPO}/${REAL_HOOKS_DIR}/puppet-git-hooks.post-update" \
&& echo "post-update hook deployed successfully" \
|| ( echo "post-update hook failed to deploy to gitolite repo" >&2 ; exit -10 )
fi
else
if [ "${INST_COMMIT}" = "1" ]; then
ln -sf "${HOOKS_DIR}/pre-commit" "${GIT_REPO}/${REAL_HOOKS_DIR}/pre-commit" \
&& echo "pre-commit hook deployed successfully" \
|| ( echo "pre-commit hook failed to deploy" >&2 ; exit -4 )
fi
if [ "${INST_RECEIVE}" = "1" ]; then
if [ "${BITBUCKET_REPO}" = "1" ]; then
# Use pre-receive.d directory and 'full' name for BitBucket
ln -sf "${HOOKS_DIR}/pre-receive" "${GIT_REPO}/${REAL_HOOKS_DIR}/pre-receive.d/puppet-git-hooks-pre-receive" \
&& echo "pre-receive hook deployed successfully" \
|| ( echo "pre-receive hook failed to deploy" >&2 ; exit -5 )
else
ln -sf "${HOOKS_DIR}/pre-receive" "${GIT_REPO}/${REAL_HOOKS_DIR}/pre-receive" \
&& echo "pre-receive hook deployed successfully" \
|| ( echo "pre-receive hook failed to deploy" >&2 ; exit -5 )
fi
fi
if [ "${INST_UPDATE}" = "1" ]; then
ln -sf "${HOOKS_DIR}/post-update" "${GIT_REPO}/${REAL_HOOKS_DIR}/post-update" \
&& echo "post-update hook deployed successfully" \
|| ( echo "post-update hook failed to deploy" >&2 ; exit -6 )
fi
fi