xref: /xnu-12377.1.9/tools/pre-commit.sh (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
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