-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhook-it
More file actions
executable file
·207 lines (183 loc) · 6.27 KB
/
hook-it
File metadata and controls
executable file
·207 lines (183 loc) · 6.27 KB
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
#!/usr/bin/env bash
# Application variables
DEFAULT_HOOKS_DIR="${DEFAULT_HOOKS_DIR:-.git/hooks}"
REPO=
SOURCE_PATH=
USE_PULL_REQUESTS=1
# 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
local sources=( $2 )
# 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 --local gitflow.branch.master) ]]; then
verbose "Initializing git flow in repository $repo"
$NOOP $GIT -C $repo flow init -fd --tag v
status=$? ; (( status )) && ERROR="Error while initializing git flow in repository $REPO" && return $status
if [[ -z $($GIT -C $repo config --local gitflow.branch.master) ]]; then
ERROR="git flow was not installed properly, please install it manually" && return 1
fi
fi
hooks_path=$($GIT -C $repo config --local 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 (( USE_PULL_REQUESTS )); then
$NOOP $GIT -C $repo config gitflow.use-pull-request true
else
$NOOP $GIT -C $repo config gitflow.use-pull-request false
fi
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
# TODO: Also handle repos with multiple languages, like go and node (wess kind of app, that have a backend and a frontend)
[[ -z $sources ]] && sources=( . "src" "backend" "src/backend" )
for source in "${sources[@]}"; do
if [[ -e $repo/$source/sfdx-project.json ]]; then
language="salesForce"
elif [[ -e $repo/$source/package.json ]]; then
language="node"
elif [[ -e $repo/$source/go.mod ]]; then
language="go"
fi
[[ -n $language ]] && break
done
if [[ -z $language ]]; then
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-path>"
echo "Options:"
#echo " -r, --recursive Inject hooks in all subfolders"
echo " --src <path> Path to the source folder used to detect language (default: repository-path folder)"
echo " --no-pr, --no-pull-request Do not use pull requests before finishing releases/hotfixes/features"
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
--no-pr|--no-pull-request)
warn "The hooks will NOT use pull requests before finishing releases/hotfixes/features"
USE_PULL_REQUESTS=0
;;
# 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;src=SOURCE_PATH" "$@"
# Set all positional arguments back in the proper order
eval set -- "${ARGS[@]}"
inject_hooks "$1" "$SOURCE_PATH" || die "$ERROR"
}
main "$@"