1#!/bin/bash 2 3# 4# Abort a commit if the code style is incorrect. 5# 6 7DENYLIST=tools/uncrustify-denylist 8UNCRUSTIFY="$(xcrun -f uncrustify)" 9 10if git rev-parse --verify HEAD >/dev/null 2>&1 ; then 11 printf >&2 "Validating code style diff against previous commit...\n" 12 against=HEAD 13else 14 # Initial commit: diff against an empty tree object 15 printf >&2 "Validating code style diff for entire source tree...\n" 16 against=$(git hash-object -t tree /dev/null) 17fi 18 19diff_with_stdin() 20{ 21 if which colordiff >/dev/null 2>&1; then 22 diff -u "$1" - | colordiff 23 else 24 diff -u "$1" - 25 fi 26} 27 28# Keep track of offending files 29staged_paths_with_format_errors=() 30 31# Note that we exclude staged deletions via --diff-filter 32for path in $(git diff --staged --name-only --diff-filter="d" $against); do 33 # Parse our deny-list to find what to skip 34 while IFS= read -r deny_path; do 35 # Skip empty lines and comments 36 if [[ -z "$deny_path" || "$deny_path" == \#* ]]; then 37 continue 38 fi 39 40 # (Prepend ./ to the path in question to match the format used in the denylist) 41 # Note that excluded directories must specify a trailing slash (or the latter string here needs tweaking) 42 if [[ "./$path" == "$deny_path" || "./$path" == "$deny_path"* ]]; then 43 # (Continue outer loop of files to be committed) 44 continue 2 45 fi 46 done < "$DENYLIST" 47 48 # Skip non-C/++ files 49 case "$path" in 50 *.c|*.h|*.cpp) 51 ;; 52 *) 53 continue 54 ;; 55 esac 56 57 printf >&2 "Validating code style for $path: " 58 59 if "$UNCRUSTIFY" -q -c tools/xnu-uncrustify.cfg --check -f "$path" >/dev/null 2>&1; then 60 printf >&2 "\e[1;32mok\e[0m.\n" 61 else 62 printf >&2 "\e[1;31minvalid style\e[0m.\n" 63 "$UNCRUSTIFY" -q -c tools/xnu-uncrustify.cfg -f "$path" | diff_with_stdin "$path" 64 staged_paths_with_format_errors+=($path) 65 fi 66done 67 68if [ ${#staged_paths_with_format_errors[@]} -ne 0 ]; then 69 path_list="${staged_paths_with_format_errors[*]}" 70 printf >&2 "\e[1;31mSome files have invalid code style, aborting commit. To reformat:\n" 71 printf >&2 "$ $UNCRUSTIFY -q -c tools/xnu-uncrustify.cfg --replace --no-backup $path_list\e[0m\n" 72 exit 1 73fi 74 75exit 0 76