#!/bin/bash ######################################################################################################### # GIT PRECOMMIT HOOK # # This script checks if the formatting of .cpp and .hpp files is correct and # # proposes to fix it automatically, let the user do it or ignore the formatting (don't do it!). # # # # This file has been entirely copied from Switcher's sources: https://github.com/sat-mtl/tools/switcher # # # ######################################################################################################### ################################## # Global variables CLANG_FORMAT="clang-format" CLANG_FORMAT_DIFF="clang-format-diff" files_unformatted="" cpp_files=() ################################### ################################## # Helpers reformat_file() { while true do read -p "Do you want to do the reformatting (M)anually or let it be done (A)utomatically? [m/A]" reply < /dev/tty case $reply in [Mm]) echo -e "Commit will be aborted, awaiting reformatting of \e[0;32m${file}\e[0m."; files_unformatted+="\t\e[0;32m$1\e[0m\n"; return;; "") ;& # Fallthrough default behaviour, the reformatting is automatic. [Aa]) echo -e "Automatic reformatting of \e[0;32m${file}\e[0m will be done now."; git diff --cached -U0 $1 | ${CLANG_FORMAT_DIFF} -i -p1; git add $1; return;; *) echo "Unrecognized option." ;; esac done } final_check() { echo -e "\n\nThe following files are not correctly formatted:" echo -e $files_unformatted while true do read -p "Do you want to (I)gnore the formatting and commit anyway (not recommended) or do the reformatting (Y)ourself ? [i/Y]" reply < /dev/tty case $reply in [Ii]) echo "Ignoring the formatting and committing files as-is."; exit 0;; "") ;& # Fallthrough default behaviour, the commit is aborted. [Yy]) echo "Commit aborted, awaiting reformatting of the previously listed files."; exit 1;; *) echo "Unrecognized option." ;; esac done } check_command() { if ! type $1 > /dev/null then echo "Error: $1 executable not found." exit 1 fi } ################################## ################################## # Main check_command $CLANG_FORMAT check_command $CLANG_FORMAT_DIFF cpp_files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.cpp$\|\.hpp$\|\.h$') # Nothing to test if no file was added, changed or modified. [ -z "$cpp_files" ] && exit 0 for file in $cpp_files do output=$(${CLANG_FORMAT} ${file} -style=file -output-replacements-xml | grep " /dev/null) if [ $? -ne 1 ] then echo -e "\e[0;31m${file} does not conform to coding standards, here are the changes needed:\n\n\e[0m$(git diff --cached -U0 ${file} | ${CLANG_FORMAT_DIFF} -p1)" reformat_file $file fi done ## All .[c|h]pp files are properly formatted. [ -z "$files_unformatted" ] && exit 0 final_check ##################################