1818
1919mkdir -p " $( go env GOPATH) /bin"
2020
21- function update_mco_tests() {
21+ update_mco_tests () {
2222 echo " Regenerating MCO evergreen tests configuration"
2323 python scripts/evergreen/e2e/mco/create_mco_tests.py > .evergreen-mco.yml
2424 git add .evergreen-mco.yml
2525}
2626
2727# Generates a yaml file to install the operator from the helm sources.
28- function generate_standalone_yaml() {
28+ generate_standalone_yaml () {
2929 HELM_OPTS=$@
3030
3131 charttmpdir=$( mktemp -d 2> /dev/null || mktemp -d -t ' charttmpdir' )
@@ -73,7 +73,7 @@ function generate_standalone_yaml() {
7373
7474}
7575
76- function python_formatting() {
76+ python_formatting () {
7777 # installing Black
7878 if ! command -v " black" > /dev/null; then
7979 pip install -r requirements.txt
@@ -85,15 +85,15 @@ function python_formatting() {
8585 black .
8686}
8787
88- function generate_manifests() {
88+ generate_manifests () {
8989 make manifests
9090
9191 git add config/crd/bases
9292 git add helm_chart/crds
9393 git add public/crds.yaml
9494}
9595
96- function update_values_yaml_files() {
96+ update_values_yaml_files () {
9797 # ensure that all helm values files are up to date.
9898 # shellcheck disable=SC2154
9999 python scripts/evergreen/release/update_helm_values_files.py
@@ -107,7 +107,7 @@ function update_values_yaml_files() {
107107 git add go.sum
108108}
109109
110- function update_release_json() {
110+ update_release_json () {
111111 # ensure that release.json is up 2 date
112112 # shellcheck disable=SC2154
113113 python scripts/evergreen/release/update_release.py
@@ -116,7 +116,7 @@ function update_release_json() {
116116 git add release.json
117117}
118118
119- function regenerate_public_rbac_multi_cluster() {
119+ regenerate_public_rbac_multi_cluster () {
120120 if echo " $git_last_changed " | grep -q -e ' cmd/kubectl-mongodb' -e ' pkg/kubectl-mongodb' ; then
121121 echo ' regenerating multicluster RBAC public example'
122122 pushd pkg/kubectl-mongodb/common/
@@ -126,78 +126,128 @@ function regenerate_public_rbac_multi_cluster() {
126126 fi
127127}
128128
129- function update_licenses() {
130- echo ' regenerating licenses'
131- time scripts/evergreen/update_licenses.sh 2>&1 | prepend " update_licenses"
132- git add LICENSE-THIRD-PARTY
129+ update_licenses () {
130+ if [[ " ${MDB_UPDATE_LICENSES:- " " } " == " true" ]]; then
131+ echo ' regenerating licenses'
132+ time scripts/evergreen/update_licenses.sh 2>&1 | prepend " update_licenses"
133+ git add LICENSE-THIRD-PARTY
134+ fi
133135}
134136
135- function check_erroneous_kubebuilder_annotations() {
137+ check_erroneous_kubebuilder_annotations () {
136138 # Makes sure there are not erroneous kubebuilder annotations that can
137139 # end up in CRDs as descriptions.
138140 if grep " // kubebuilder" ./* -r --exclude-dir=vendor --include=\* .go; then
139- echo " Found an erroneous kubebuilder annotation"
141+ echo -e " ${RED} Found an erroneous kubebuilder annotation${NO_COLOR} "
140142 exit 1
141143 fi
142144}
143145
144- function check_incorrect_makefile_variable_brackets() {
146+ check_incorrect_makefile_variable_brackets () {
145147 if find . -name " Makefile" | grep -v vendor | xargs grep " \$ {" ; then
146- echo ' ERROR: Makefiles should NEVER contain curly brackets variables'
148+ echo -e " ${RED} ERROR: Makefiles should NEVER contain curly brackets variables${NO_COLOR} "
147149 exit 1
148150 fi
149151}
150152
151- function pre_commit() {
152- if [[ " ${MDB_UPDATE_LICENSES:- " " } " == " true" ]]; then
153- ( (time update_licenses) 2>&1 | prepend " update_licenses" ) &
154- fi
155- ( (time scripts/evergreen/lint_code.sh) 2>&1 | prepend " lint_code.sh" ) &
156- ( (time start_shellcheck) 2>&1 | prepend " shellcheck" ) &
153+ update_jobs () {
154+ # Update release.json first in case there is a newer version
155+ time update_release_json
156+ # We need to generate the values files first
157+ time update_values_yaml_files
158+ # The values files are used for generating the standalone yaml
159+ time generate_standalone_yaml
160+ }
157161
158- # Update release.json first in case there is a newer version
159- (time update_release_json) 2>&1 | prepend " update_release_json"
160- # We need to generate the values files first
161- (time update_values_yaml_files) 2>&1 | prepend " update_values_yaml_files"
162- # The values files are used for generating the standalone yaml
163- (time generate_standalone_yaml) 2>&1 | prepend " generate_standalone_yaml"
162+ lint_code () {
163+ scripts/evergreen/lint_code.sh
164+ }
165+
166+ # bg_job_ vars are global; run_job_in_background function is appending to them on each call
167+ bg_job_pids=()
168+ bg_job_pids_with_names=()
169+
170+ get_job_name () {
171+ local search_pid=" $1 "
172+ local match
173+ match=$( printf ' %s\n' " ${bg_job_pids_with_names[@]} " | grep " ^${search_pid} :" )
174+ echo " ${match#*: } " # Remove everything up to and including the colon
175+ }
164176
165- ( (time regenerate_public_rbac_multi_cluster) 2>&1 | prepend " regenerate_public_rbac_multi_cluster" ) &
177+ # Executes function given on the first argument as background job.
178+ # It's ensuring logs are properly prefixed by the name and
179+ # the job's pid is captured in bg_jobs array in order to wait for completion.
180+ run_job_in_background () {
181+ job_name=$1
182+ time ${job_name} 2>&1 | prepend " ${job_name} " &
183+
184+ local job_pid=$!
185+ bg_job_pids+=(" ${job_pid} " )
186+ bg_job_pids_with_names+=(" ${job_pid} :${job_name} " )
187+ echo " Started ${job_name} with PID: ${job_pid} "
188+ }
166189
167- # Run black and isort on python files that have changed
168- ( (time python_formatting) 2>&1 | prepend " python_formatting" ) &
190+ # Waits for all background jobs stored in bg_job_pids and check their exit codes.
191+ wait_for_all_background_jobs () {
192+ failures=()
193+ for pid in " ${bg_job_pids[@]} " ; do
194+ wait " ${pid} " || {
195+ job_name=$( get_job_name " ${pid} " )
196+ failures+=(" ${RED}${job_name} (PID ${pid} )${NO_COLOR} " )
197+ }
198+ done
199+
200+ if [[ ${# failures[@]} -gt 0 ]]; then
201+ echo -e " ${RED} Some checks have failed:${NO_COLOR} "
202+ for failure in " ${failures[@]} " ; do
203+ echo -e " $failure "
204+ done
205+ echo -e " ${RED} To see the details look for the job's logs by it's prefixed name (e.g. \" shellcheck:\" ).${NO_COLOR} "
206+ return 1
207+ fi
169208
170- ( (time check_erroneous_kubebuilder_annotations) 2>&1 | prepend " check_erroneous_kubebuilder_annotations" ) &
209+ return 0
210+ }
171211
172- wait
212+ pre_commit () {
213+ run_job_in_background " update_jobs"
214+ run_job_in_background " update_licenses"
215+ run_job_in_background " lint_code"
216+ run_job_in_background " start_shellcheck"
217+ run_job_in_background " regenerate_public_rbac_multi_cluster"
218+ run_job_in_background " python_formatting"
219+ run_job_in_background " check_erroneous_kubebuilder_annotations"
220+
221+ if wait_for_all_background_jobs; then
222+ echo -e " ${GREEN} pre-commit: All checks passed!${NO_COLOR} "
223+ return 0
224+ else
225+ return 1
226+ fi
173227}
174228
175229# Function to run shellcheck on a single file
176230run_shellcheck () {
177231 local file=" $1 "
178232 echo " Running shellcheck on $file "
179233 if ! shellcheck --color=always -x " $file " -e SC2154 -e SC1091 -e SC1090 -e SC2148 -o require-variable-braces -P " scripts" ; then
180- echo " shellcheck failed on $file "
234+ echo -e " ${RED} shellcheck failed on $file ${NO_COLOR} "
181235 exit 1
182236 fi
183237}
184238
185- start_shellcheck () {
186- files_1=$( find scripts -type f -name " *.sh" )
187- files_2=$( find scripts/dev/contexts -type f | grep -v private-context)
188- files_3=$( find scripts/funcs -type f)
189- files_4=$( find public/architectures -type f -name " *.sh" )
190- files=$( echo -e " $files_1 \n$files_2 \n$files_3 \n$files_4 " )
191- # Process each file in parallel
192- for file in $files ; do
193- run_shellcheck " $file " &
194- done
195-
196- # Wait for all background jobs
197- for job in $( jobs -p) ; do
198- wait " $job " || exit 1
199- done
239+ # Export function so it's available in subshells (for xargs)
240+ export -f run_shellcheck
200241
242+ start_shellcheck () {
243+ # shellcheck disable=SC2016
244+ {
245+ find scripts -type f -name " *.sh"
246+ find scripts/dev/contexts -type f | grep -v private-context
247+ find scripts/funcs -type f
248+ find public/architectures -type f -name " *.sh"
249+ find docs/ -type f -name " *.sh"
250+ } | xargs -I {} -P 20 bash -c ' run_shellcheck "$1"' _ {}
201251}
202252
203253cmd=${1:- " pre-commit" }
@@ -210,5 +260,5 @@ elif [[ "${cmd}" == "pre-commit" ]]; then
210260elif [[ " ${cmd} " == " shellcheck" ]]; then
211261 start_shellcheck
212262elif [[ " ${cmd} " == " lint" ]]; then
213- source scripts/evergreen/ lint_code.sh
263+ lint_code
214264fi
0 commit comments