#!/bin/bash
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
set -e
set -o pipefail
# trap 'echo ERROR on line: $LINENO running command: $BASH_COMMAND ; trap - EXIT; exit $?' EXIT
# Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
# taken from: https://raw.githubusercontent.com/andrewseidl/githook-clang-format/master/clang-format.hook
# - with just added check for cpp file & check for proper version of clang-format
# - with use of clang-format diff.py - for changed chunk changes only
# might be worth to consider: https://github.com/Sarcasm/run-clang-format
# shellcheck source=../config/format-config.sh
# shellcheck source=../config/clang/colors.sh
# shellcheck source=../config/clang/common.sh
L_GIT_DIR=$(git rev-parse --show-toplevel)
source $L_GIT_DIR/config/format-config.sh
source $L_GIT_DIR/config/clang/colors.sh
source $L_GIT_DIR/config/clang/clang-common.sh
# if autoformatting was disabled by user - then ignore this commit hook
if [ "$DISABLE_AUTO_FORMATTING" -eq 1 ]; then
[[ $VERBOSE ]] && echo "auto formatting is disabled"
exit 0
fi
verify_clang_format_version
L_CLANG_DIFF_TOOL=$(get_clang_format)
if ! [[ $L_CLANG_DIFF_TOOL ]] || [[ $L_CLANG_DIFF_TOOL == "" ]]; then
[[ $VERBOSE ]] && echo "clang tool not found"
exit 1
fi
check_file() {
file="${1}"
last_commit="${2}"
if [ -f "${file}" ]; then
#[[ $VERBOSE ]] && echo -en "Checking: \e[33m${file}\e[0m :\t"
results["${file}"]="${OK}"
case ${last_commit} in
"True")
if [[ ${FIX,,} == "true" ]]; then
git diff -U0 --no-color remotes/origin/master...HEAD "${file}" | ${L_CLANG_DIFF_TOOL} -style file -p1 -i
STATUS=$(git status --short -- "${file}")
if [ -n "${STATUS}" ]; then
git add "${file}"
results["${file}"]="${FIXED}";
fi
else
OUT=$(git diff -U0 --no-color remotes/origin/master...HEAD "${file}" | ${L_CLANG_DIFF_TOOL} -style file -p1 )
if [ -n "${OUT}" ]; then
results["${file}"]="${ERROR}"
return 1
fi
fi
;;
"Stage")
if [[ ${FIX,,} == "true" ]]; then
git diff -U0 --no-color --cached "${file}" | ${L_CLANG_DIFF_TOOL} -style file -p1 -i
STATUS=$(git status --short -- "${file}")
if [ -n "${STATUS}" ]; then
git add "${file}"
results["${file}"]="${FIXED}";
fi
else
OUT=$(git diff -U0 --no-color --cached "${file}" | ${L_CLANG_DIFF_TOOL} -style file -p1)
if [ -n "${OUT}" ]; then
results["${file}"]="${ERROR}"
return 1
fi
fi
;;
*)
OUT=$(git diff -U0 --no-color --cached "${file}" | ${L_CLANG_DIFF_TOOL} -style file -p1 )
if [[ -n ${OUT} ]]; then
results["${file}"]="${ERROR}"
return 1
fi
;;
esac
fi
return 0
}
function help() {
echo "Runs clang-format on source files"
cat <<- EOM
usage:
$0 [option]
--about does nothing
--last checks current branch against origin/master - doesn't fix
--branch-fix checks current branch against origin/master and fixes errors - you have to 'git add' and 'git commit' them
--fix fix style in currently staged files (ignores user.fixinstage variale), this is usefull for manual style applying
If you would like to automatically fix style before commit
add to your git config "user.fixinstage" variable with value "True"
by calling:
git config user.fixinstage True
EOM
}
case "${1}" in
--about|--help )
help
FILES=''
LAST=""
exit 0
;;
--last)
FILES=$(git diff --name-only remotes/origin/master...HEAD)
LAST="True"
FIX="false"
;;
--branch-fix)
FILES=$(git diff --name-only remotes/origin/master...HEAD)
LAST="True"
FIX="true"
;;
--fix)
FILES=$(git diff-index --cached --name-only HEAD)
LAST="Stage"
FIX=true
;;
*)
if [[ $# -ne 0 ]]; then
echo "unknown parameters: '$*'"
help
exit 1
fi
FILES=$(git diff-index --cached --name-only HEAD)
LAST="Stage"
FIX=$([[ $(git config user.fixinstage) ]] && git config user.fixinstage || echo "false")
FIX=${FIX:-false}
;;
esac
declare -A results
EXIT_CODE=0
for file in ${FILES}; do
if [[ ${file} =~ ^.*\.(cpp|hpp|c|h|cxx|gcc|cc)$ ]] && shouldnt_ignore ${file}; then
check_file "${file}" ${LAST} || RESULT=$?
if [[ ${RESULT} -eq 1 ]]; then
EXIT_CODE=1
fi
fi
done
for FILE in "${!results[@]}"
do
echo -e " ${FILE} : ${results[${FILE}]}"
done
echo "exit: ${EXIT_CODE}"
exit ${EXIT_CODE}