-
Notifications
You must be signed in to change notification settings - Fork 1
/
hook-it
executable file
·181 lines (158 loc) · 5 KB
/
hook-it
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
#!/usr/bin/env bash
# Application variables
DEFAULT_HOOKS_DIR="${DEFAULT_HOOKS_DIR:-.git/hooks}"
REPO=
# General variables
ASSUMEYES=1
FORCE=0
NOOP=
ERROR=
VERBOSE=0
ARGS=()
GIT=${GIT:-git}
source hooks/common/functions.sh
function is_git() {
[[ ! -d $1 ]] && ERROR="Folder $REPO does not exist" && return 1
[[ ! -d $1/.git ]] && ERROR="Folder $REPO is not a git repository" && return 2
return 0
}
function inject_hooks() {
local status
local language
local hooks_path
local repo=$1
# 0/ validation
is_git $repo || return $?
verbose "Injecting git hooks into $repo"
# 1/ make sure git flow is initialized
if [[ -z $($GIT -C $repo config gitflow.branch.master) ]]; then
verbose "Initializing git flow in repository $repo"
$NOOP $GIT -C $repo flow init -d --tag v
status=$? ; (( status )) && ERROR="Error while initializing git flow in repository $REPO" && return $status
fi
hooks_path=$($GIT -C $repo config gitflow.path.hooks)
if [[ -z $hooks_path ]]; then
ERROR="git flow AVH edition is needed for this to work" && return 1
fi
hooks_path="${repo}/${DEFAULT_HOOKS_DIR}" # Resetting the hooks folder, in case the repo was moved
# 2/ configure git flow
verbose "Configuring gitflow"
$NOOP $GIT -C $repo config gitflow.path.hooks "$hooks_path"
$NOOP $GIT -C $repo config gitflow.prefix.versiontag "v"
$NOOP $GIT -C $repo config gitflow.hotfix.finish.message "Hotfix %tag%"
$NOOP $GIT -C $repo config gitflow.release.finish.message "Release %tag%"
if [[ -z $($GIT -C $repo config --get gitflow.allow-master-commit) ]]; then
$NOOP $GIT -C $repo config gitflow.allow-master-commit false
fi
if [[ -z $($GIT -C $repo config --get gitflow.allow-conflict-commit) ]]; then
$NOOP $GIT -C $repo config gitflow.allow-conflict-commit false
fi
# 3/ find language
if [[ -e $repo/package.json ]]; then
language="node"
elif [[ -e $repo/go.mod ]]; then
language="go"
else
ERROR="Unable to find language for $repo" && return 1
fi
verbose "Language: $language"
# 3/ copy hooks
if [[ ! -d $hooks_path ]]; then
$NOOP mkdir -p $hooks_path
status=$? ; (( status )) && ERROR="Error while creating hooks folder $hooks_path" && return $status
fi
verbose "Copying hooks"
$NOOP cp -f hooks/common/* $hooks_path/
status=$? ; (( status )) && ERROR="Error while copying common hooks to $hooks_path" && return $status
$NOOP cp -f hooks/$language/* $hooks_path/
status=$? ; (( status )) && ERROR="Error while copying $language hooks to $hooks_path" && return $status
return 0
}
function usage() {
echo "Usage: $0 [options] <repository>"
echo "Options:"
#echo " -r, --recursive Inject hooks in all subfolders"
echo " -h, --help Display this help message"
echo " --noop, --dry-run Do not execute any command, just display what would be done"
echo " --quiet Do not display any message"
echo " -v, --verbose Increase verbosity"
echo " -y, --yes Assume yes to all questions"
}
function parse_args() {
local parse_config="${1};"
declare -A options
shift
while [[ $parse_config ]]; do
local option_config=${parse_config%%;*}
local option_names="${option_config%%=*},"
local option_code=${option_config#*=}
while [[ $option_names ]]; do
local option_name=${option_names%%,*}
if [[ ${#option_name} == 1 ]]; then
options["-${option_name}"]="${option_code}"
else
options["--${option_name}"]="${option_code}"
fi
option_names=${option_names#*,}
done
parse_config=${parse_config#*;}
done
while (( "$#" )); do
# Replace --parm=arg with --parm arg
[[ $1 == --*=* ]] && set -- "${1%%=*}" "${1#*=}" "${@:2}"
if [[ -n ${options[$1]} ]]; then
local action=${options[$1]}
if [[ ${action:0:1} == "*" ]]; then
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
eval "${action:1}=$2"
shift 2
continue
else
eval "${action}=1"
fi
else
case $1 in
# Standard options
--force)
warn "This program will force operations to be executed"
FORCE=1
;;
--help|-h|-\?)
usage
exit 0
;;
--noop|--dry_run|--dry-run)
warn "This program will execute in dry mode, your system will not be modified"
NOOP=:
;;
--quiet)
VERBOSE=0
;;
-v|--verbose)
VERBOSE=$((VERBOSE + 1))
;;
-y|--yes|--assumeyes|--assume_yes|--assume-yes)
ASSUMEYES=1
;;
-?*|--*=) # Invalid options
warn "Unknown option $1 will be ignored"
;;
--) # Force end of options
shift
break
;;
*) # Positional Argument
ARGS+=( "$1" )
;;
esac
fi
shift
done
}
function main() {
parse_args "r,recursive=RECURSIVE" "$@"
# Set all positional arguments back in the proper order
eval set -- "${ARGS[@]}"
inject_hooks "$1" || die "$ERROR"
}
main "$@"