@@ -59,6 +59,21 @@ GIT_CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
5959# Determine root directory:
6060root=$( git rev-parse --show-toplevel)
6161
62+ # Define the path to a directory for caching hook results:
63+ cache_dir=" ${root} /.git/hooks-cache"
64+
65+ # Define the path to a file for storing hook results:
66+ cache_file=" ${cache_dir} /pre_push_report.yml"
67+
68+ # Resolve the last commit message (excluding meta data such as author name and date):
69+ commit_message=$( git log -1 --pretty=%B)
70+
71+ # Define the path to a file for storing a backup of the last commit message:
72+ backup_commit_file=" ${cache_dir} /last_commit_message.backup"
73+
74+ # Define the path to a file for storing a new (i.e., amended) commit message:
75+ new_commit_file=" ${cache_dir} /new_commit_message.txt"
76+
6277
6378# FUNCTIONS #
6479
@@ -72,9 +87,83 @@ on_error() {
7287
7388# Runs clean-up tasks.
7489cleanup () {
90+ finalize_cache
91+ create_new_commit_file
92+ amend_commit
7593 echo ' ' >&2
7694}
7795
96+ # Creates a directory for caching hook results to allow accessing those results in subsequent hooks.
97+ create_cache_dir () {
98+ mkdir " ${cache_dir} "
99+ }
100+
101+ # Removes any previous hook results.
102+ clean_cache_file () {
103+ rm -f " ${cache_file} "
104+ }
105+
106+ # Appends results to a file containing hook results.
107+ #
108+ # $1 - result line
109+ write_to_cache () {
110+ echo " $1 " >> " ${cache_file} "
111+ }
112+
113+ # Initializes a new cache file for storing hook results.
114+ init_cache_file () {
115+ touch " ${cache_file} "
116+ write_to_cache ' ---'
117+ write_to_cache ' type: pre_push_report'
118+ write_to_cache ' description: Results of running various checks prior to pushing changes.'
119+ write_to_cache ' report:'
120+ }
121+
122+ # Creates a backup of the last commit message.
123+ backup_last_commit_message () {
124+ echo " ${commit_message} " > " ${backup_commit_file} "
125+ }
126+
127+ # Runs initialization tasks.
128+ init () {
129+ create_cache_dir
130+ clean_cache_file
131+ init_cache_file
132+ backup_last_commit_message
133+ return 0
134+ }
135+
136+ # Adds a new task to hook results.
137+ #
138+ # $1 - task name
139+ add_task () {
140+ write_to_cache " - task: $1 "
141+ }
142+
143+ # Saves the task status in the hook results.
144+ #
145+ # $1 - task status
146+ task_status () {
147+ write_to_cache " status: $1 "
148+ }
149+
150+ # Finalizes hook results.
151+ finalize_cache () {
152+ write_to_cache ' ---'
153+ }
154+
155+ # Creates a file containing a new (amended) commit message.
156+ create_new_commit_file () {
157+ echo " ${commit_message} " > " ${new_commit_file} "
158+ echo ' ' >> " ${new_commit_file} "
159+ cat " ${cache_file} " >> " ${new_commit_file} "
160+ }
161+
162+ # Amends the last commit to include the hook results.
163+ amend_commit () {
164+ git commit --amend --no-edit --file=" ${new_commit_file} "
165+ }
166+
78167# Checks if commits exist to push, as `git push` will execute regardless of whether commits exist to push or not.
79168has_commits () {
80169 local commits
@@ -115,6 +204,10 @@ main() {
115204 local changed_files
116205 local files
117206
207+ init
208+ if [[ " $? " -ne 0 ]]; then
209+ on_error 1
210+ fi
118211 has_commits
119212 if [[ " $? " -ne 0 ]]; then
120213 on_error 1
@@ -128,163 +221,249 @@ main() {
128221 changed_files=$( git diff --name-only --cached --diff-filter ACMR " ${remote} /${GIT_CURRENT_BRANCH} " | sed -e " s#^#${root} \\ /#" )
129222
130223 # Run JavaScript example files:
224+ add_task ' run_javascript_examples'
131225 if [[ -z " ${skip_javascript_examples} " ]]; then
132226 files=$( echo " ${changed_files} " | grep ' /examples/.*\.js$' | grep -v ' /examples/fixtures/.*\.js$' | tr ' \n' ' ' )
133227 if [[ -n " ${files} " ]]; then
134228 echo ' Running JavaScript example files...' >&2
135229 make FILES=" ${files} " examples-javascript-files > /dev/null >&2
136230 if [[ " $? " -ne 0 ]]; then
231+ task_status ' failed'
137232 echo ' ' >&2
138233 echo ' Encountered an error when running JavaScript examples.' >&2
139234 on_error 1
140235 fi
236+ task_status ' passed'
237+ else
238+ task_status ' na'
141239 fi
240+ else
241+ task_status ' skipped'
142242 fi
143243 # Run C example files...
244+ add_task ' run_c_examples'
144245 if [[ -z " ${skip_c_examples} " ]]; then
145246 files=$( echo " ${changed_files} " | grep ' /examples/.*\.c$' | grep -v ' /examples/fixtures/.*\.c$' | tr ' \n' ' ' )
146247 if [[ -n " ${files} " ]]; then
147248 echo ' Running C example files...' >&2
148249 make FILES=" ${files} " examples-c-files > /dev/null >&2
149250 if [[ " $? " -ne 0 ]]; then
251+ task_status ' failed'
150252 echo ' ' >&2
151253 echo ' Encountered an error when running C examples.' >&2
152254 on_error 1
153255 fi
256+ task_status ' passed'
257+ else
258+ task_status ' na'
154259 fi
260+ else
261+ task_status ' skipped'
155262 fi
156263 # Run C++ example files...
264+ add_task ' run_cpp_examples'
157265 if [[ -z " ${skip_cpp_examples} " ]]; then
158266 files=$( echo " ${changed_files} " | grep ' /examples/.*\.cpp$' | grep -v ' /examples/fixtures/.*\.cpp$' | tr ' \n' ' ' )
159267 if [[ -n " ${files} " ]]; then
160268 echo ' Running C++ example files...' >&2
161269 make FILES=" ${files} " examples-cpp-files > /dev/null >&2
162270 if [[ " $? " -ne 0 ]]; then
271+ task_status ' failed'
163272 echo ' ' >&2
164273 echo ' Encountered an error when running C++ examples.' >&2
165274 on_error 1
166275 fi
276+ task_status ' passed'
277+ else
278+ task_status ' na'
167279 fi
280+ else
281+ task_status ' skipped'
168282 fi
169283 # Run JavaScript examples in README files:
284+ add_task ' run_javascript_readme_examples'
170285 if [[ -z " ${skip_javascript_readme_examples} " ]]; then
171286 files=$( echo " ${changed_files} " | grep ' README.md$' | grep -v ' ^tools/' | tr ' \n' ' ' )
172287 if [[ -n " ${files} " ]]; then
173288 echo ' Running README JavaScript examples...' >&2
174289 make FILES=" ${files} " markdown-examples-javascript-files > /dev/null >&2
175290 if [[ " $? " -ne 0 ]]; then
291+ task_status ' failed'
176292 echo ' ' >&2
177293 echo ' Encountered an error when running README JavaScript examples.' >&2
178294 on_error 1
179295 fi
296+ task_status ' passed'
297+ else
298+ task_status ' na'
180299 fi
300+ else
301+ task_status ' skipped'
181302 fi
182303
183304 # TODO: run CLI examples found in Markdown files
184305
306+ # TODO: compile and run C examples found in Markdown files
307+
185308 # Run C benchmark files...
309+ add_task ' run_c_benchmarks'
186310 if [[ -z " ${skip_c_benchmarks} " ]]; then
187311 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.c$' | tr ' \n' ' ' )
188312 if [[ -n " ${files} " ]]; then
189313 echo ' Running C benchmark files...' >&2
190314 make FILES=" ${files} " benchmark-c-files > /dev/null >&2
191315 if [[ " $? " -ne 0 ]]; then
316+ task_status ' failed'
192317 echo ' ' >&2
193318 echo ' Encountered an error when running C benchmarks.' >&2
194319 on_error 1
195320 fi
321+ task_status ' passed'
322+ else
323+ task_status ' na'
196324 fi
325+ else
326+ task_status ' skipped'
197327 fi
198328 # Run C++ benchmark files...
329+ add_task ' run_cpp_benchmarks'
199330 if [[ -z " ${skip_cpp_benchmarks} " ]]; then
200331 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.cpp$' | tr ' \n' ' ' )
201332 if [[ -n " ${files} " ]]; then
202333 echo ' Running C++ benchmark files...' >&2
203334 make FILES=" ${files} " benchmark-cpp-files > /dev/null >&2
204335 if [[ " $? " -ne 0 ]]; then
336+ task_status ' failed'
205337 echo ' ' >&2
206338 echo ' Encountered an error when running C++ benchmarks.' >&2
207339 on_error 1
208340 fi
341+ task_status ' passed'
342+ else
343+ task_status ' na'
209344 fi
345+ else
346+ task_status ' skipped'
210347 fi
211348 # Run Fortran benchmark files...
349+ add_task ' run_fortran_benchmarks'
212350 if [[ -z " ${skip_fortran_benchmarks} " ]]; then
213351 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.f$' | tr ' \n' ' ' )
214352 if [[ -n " ${files} " ]]; then
215353 echo ' Running Fortran benchmark files...' >&2
216354 make FILES=" ${files} " benchmark-fortran-files > /dev/null >&2
217355 if [[ " $? " -ne 0 ]]; then
356+ task_status ' failed'
218357 echo ' ' >&2
219358 echo ' Encountered an error when running Fortran benchmarks.' >&2
220359 on_error 1
221360 fi
361+ task_status ' passed'
362+ else
363+ task_status ' na'
222364 fi
365+ else
366+ task_status ' skipped'
223367 fi
224368 # Run JavaScript benchmark files...
369+ add_task ' run_javascript_benchmarks'
225370 if [[ -z " ${skip_javascript_benchmarks} " ]]; then
226371 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.js$' | tr ' \n' ' ' )
227372 if [[ -n " ${files} " ]]; then
228373 echo ' Running JavaScript benchmark files...' >&2
229374 make FILES=" ${files} " benchmark-javascript-files > /dev/null >&2
230375 if [[ " $? " -ne 0 ]]; then
376+ task_status ' failed'
231377 echo ' ' >&2
232378 echo ' Encountered an error when running JavaScript benchmarks.' >&2
233379 on_error 1
234380 fi
381+ task_status ' passed'
382+ else
383+ task_status ' na'
235384 fi
385+ else
386+ task_status ' skipped'
236387 fi
237388 # Run Julia benchmark files...
389+ add_task ' run_julia_benchmarks'
238390 if [[ -z " ${skip_julia_benchmarks} " ]]; then
239391 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.jl$' | tr ' \n' ' ' )
240392 if [[ -n " ${files} " ]]; then
241393 echo ' Running Julia benchmark files...' >&2
242394 make FILES=" ${files} " benchmark-julia-files > /dev/null >&2
243395 if [[ " $? " -ne 0 ]]; then
396+ task_status ' failed'
244397 echo ' ' >&2
245398 echo ' Encountered an error when running Julia benchmarks.' >&2
246399 on_error 1
247400 fi
401+ task_status ' passed'
402+ else
403+ task_status ' na'
248404 fi
405+ else
406+ task_status ' skipped'
249407 fi
250408 # Run Python benchmark files...
409+ add_task ' run_python_benchmarks'
251410 if [[ -z " ${skip_python_benchmarks} " ]]; then
252411 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.py$' | tr ' \n' ' ' )
253412 if [[ -n " ${files} " ]]; then
254413 echo ' Running Python benchmark files...' >&2
255414 make FILES=" ${files} " benchmark-python-files > /dev/null >&2
256415 if [[ " $? " -ne 0 ]]; then
416+ task_status ' failed'
257417 echo ' ' >&2
258418 echo ' Encountered an error when running Python benchmarks.' >&2
259419 on_error 1
260420 fi
421+ task_status ' passed'
422+ else
423+ task_status ' na'
261424 fi
425+ else
426+ task_status ' skipped'
262427 fi
263428 # Run R benchmark files...
429+ add_task ' run_r_benchmarks'
264430 if [[ -z " ${skip_r_benchmarks} " ]]; then
265431 files=$( echo " ${changed_files} " | grep ' /benchmark/.*\.R$' | tr ' \n' ' ' )
266432 if [[ -n " ${files} " ]]; then
267433 echo ' Running R benchmark files...' >&2
268434 make FILES=" ${files} " benchmark-r-files > /dev/null >&2
269435 if [[ " $? " -ne 0 ]]; then
436+ task_status ' failed'
270437 echo ' ' >&2
271438 echo ' Encountered an error when running R benchmarks.' >&2
272439 on_error 1
273440 fi
441+ task_status ' passed'
442+ else
443+ task_status ' na'
274444 fi
445+ else
446+ task_status ' skipped'
275447 fi
276448 # Run JavaScript test files...
449+ add_task ' run_javascript_tests'
277450 if [[ -z " ${skip_javascript_tests} " ]]; then
278451 files=$( echo " ${changed_files} " | grep ' /test/.*\.js$' | grep -v ' /test/fixtures/.*\.js$' | grep -v ' /test/.*/fixtures/.*\.js$' | tr ' \n' ' ' )
279452 if [[ -n " ${files} " ]]; then
280453 echo ' Running JavaScript test files...' >&2
281454 make FILES=" ${files} " test-javascript-files > /dev/null >&2
282455 if [[ " $? " -ne 0 ]]; then
456+ task_status ' failed'
283457 echo ' ' >&2
284458 echo ' Encountered an error when running JavaScript tests.' >&2
285459 on_error 1
286460 fi
461+ task_status ' passed'
462+ else
463+ task_status ' na'
287464 fi
465+ else
466+ task_status ' skipped'
288467 fi
289468
290469 cleanup
0 commit comments