|
4 | 4 | # This source code is licensed under the BSD-style license found in the
|
5 | 5 | # LICENSE file in the root directory of this source tree.
|
6 | 6 |
|
7 |
| -# Check 1: If commit header contains WIP, everything is ok |
8 |
| -git rev-list --format=%s --max-count=1 HEAD | grep -q WIP && exit 0 |
9 |
| - |
10 |
| -# Check 2: lintunner on latest patches. |
11 |
| -lintrunner --revision 'HEAD^' |
12 |
| -if [[ $? != 0 ]] |
13 |
| - then |
14 |
| - echo "Failed linting" |
15 |
| - exit 1 |
| 7 | +RESET='\e[0m' |
| 8 | +RED='\e[31m' |
| 9 | +GREEN='\e[32m' |
| 10 | +YELLOW='\e[33m' |
| 11 | +BLUE='\e[34m' |
| 12 | + |
| 13 | +INFO="${BLUE}[INFO]${RESET}" |
| 14 | +WARNING="${YELLOW}[WARNING]${RESET}" |
| 15 | +ERROR="${RED}[ERROR]${RESET}" |
| 16 | +SUCCESS="${GREEN}[SUCCESS]${RESET}" |
| 17 | + |
| 18 | +# This list of imperative verbs was compiled from the entire list of Executorch |
| 19 | +# commits. It should be fairly exhaustive, but add more verbs if you find one |
| 20 | +# that's missing. |
| 21 | +VERBS="Add|Fix|Update|Refactor|Improve|Remove|Change|Implement|Create|Modify|"\ |
| 22 | +"Enable|Integrate|Make|Support|Deprecate|Extend|Enhance|Convert|Rewrite|Unify|"\ |
| 23 | +"Optimize|Expand|Reorganize|Adjust|Streamline|Clarify|Introduce|Document|"\ |
| 24 | +"Polish|Standardize|Revise|Simplify|Restore|Resolve|Replace|Suppress|Migrate|"\ |
| 25 | +"Generate|Delete|Exclude|Register|Include|Upgrade|Validate|Verify|Refine|"\ |
| 26 | +"Reimplement|Patch|Sync|Revert|Fixup|Enhance|Append|Annotate|Disable|Emit|"\ |
| 27 | +"Handle|Ignore|Interpret|Instantiate|Invoke|Limit|Load|Modify|Permit|Print|"\ |
| 28 | +"Profile|Recalculate|Reconstruct|Redefine|Redesign|Reevaluate|Relocate|Remap|"\ |
| 29 | +"Render|Reposition|Request|Revert|Sanitize|Specify|Strengthen|Stub|Substitute|"\ |
| 30 | +"Tag|Tweak|Unify|Unlock|Unset|Use|Validate|Verify" |
| 31 | + |
| 32 | +# Remote branch |
| 33 | +REMOTE=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null) |
| 34 | + |
| 35 | +if [ -z "$REMOTE" ]; then |
| 36 | + echo -e "${WARNING} Could not find upstream branch to compare to." |
| 37 | + echo "Please specify the number of commits you are pushing." |
| 38 | + echo -n "Enter number of commits to check (default 1): " > /dev/tty |
| 39 | + read NUM_COMMITS < /dev/tty |
| 40 | + NUM_COMMITS=${NUM_COMMITS:-1} # Default to 1 if empty |
| 41 | + RANGE=$(git rev-list HEAD -n "$NUM_COMMITS") |
| 42 | + COMMITS=${RANGE} |
| 43 | +elif [ "$(git rev-parse --abbrev-ref HEAD)" == "HEAD" ]; then |
| 44 | + echo -e "${WARNING} You're in a detached HEAD state." |
| 45 | + echo "Please specify the number of commits you are pushing." |
| 46 | + echo -n "Enter number of commits to check (default 1): " > /dev/tty |
| 47 | + read NUM_COMMITS < /dev/tty |
| 48 | + NUM_COMMITS=${NUM_COMMITS:-1} # Default to 1 if empty |
| 49 | + RANGE=$(git rev-list HEAD -n "$NUM_COMMITS") |
| 50 | + COMMITS=${RANGE} |
| 51 | +else |
| 52 | + # Determine commits to check |
| 53 | + RANGE="$REMOTE..HEAD" |
| 54 | + COMMITS=$(git rev-list "$RANGE") |
| 55 | +fi |
| 56 | + |
| 57 | +if [ -z "$COMMITS" ]; then |
| 58 | + echo -e "${INFO} No new commits to check." |
| 59 | + exit 0 |
16 | 60 | fi
|
17 | 61 |
|
18 |
| -# Check 3: License headers |
19 |
| -# We do a simple check of if all committed headers contain "$current_year Arm". |
20 |
| -# This does not guarantee OK in ci but should be ok most of the time. |
| 62 | +for COMMIT in ${COMMITS}; do |
| 63 | + # If commit header contains WIP, everything is ok |
| 64 | + git rev-list --format=%s --max-count=1 ${COMMIT} | grep -q WIP && \ |
| 65 | + continue |
| 66 | + |
| 67 | + echo -e "${INFO} Checking commit ${COMMIT}" |
| 68 | + |
| 69 | + # lintrunner on latest patches. |
| 70 | + echo -e "${INFO} Lintrunner" |
| 71 | + lintrunner --revision ${COMMIT} |
| 72 | + if [[ $? != 0 ]]; then |
| 73 | + echo -e "${ERROR} Failed linting" |
| 74 | + FAILED=1 |
| 75 | + else |
| 76 | + echo -e "${SUCCESS} Lintrunner OK" |
| 77 | + fi |
| 78 | + |
| 79 | + # Check license headers |
| 80 | + # We do a simple check of if all committed headers contain |
| 81 | + # "$current_year Arm". This does not guarantee OK in ci but should be ok |
| 82 | + # most of the time. |
| 83 | + echo -e "${INFO} License check" |
| 84 | + |
| 85 | + current_year=$(date +%Y) |
| 86 | + failed_license_check=false |
| 87 | + commit_files=$(git diff-tree --no-commit-id --name-only \ |
| 88 | + --diff-filter=ACMR ${COMMIT} -r) |
| 89 | + for commited_file in $commit_files; do |
| 90 | + head $commited_file | grep -q "$current_year Arm" |
| 91 | + if [[ $? != 0 ]]; then |
| 92 | + echo -e "${ERROR} Header in $commited_file did not contain"\ |
| 93 | + "'$current_year Arm'" |
| 94 | + failed_license_check=true |
| 95 | + else |
| 96 | + echo -e "${SUCCESS} $commited_file passed license check" |
| 97 | + fi |
| 98 | + done |
| 99 | + |
| 100 | + if [[ $failed_license_check == true ]]; then |
| 101 | + FAILED=1 |
| 102 | + else |
| 103 | + echo -e "${SUCCESS} All files passed license check" |
| 104 | + fi |
| 105 | + |
| 106 | + # Check commit message |
| 107 | + echo -e "${INFO} Checking commit message" |
| 108 | + COMMIT_MSG=$(git log -1 --format=%B "$COMMIT") |
21 | 109 |
|
22 |
| -current_year=$(date +%Y) |
23 |
| -failed_license_check=false |
24 |
| -commit_files=$(git diff-tree --no-commit-id --name-only --diff-filter=ACMR HEAD -r) |
| 110 | + SUBJECT=$(echo "$COMMIT_MSG" | head -n1) |
| 111 | + BODY=$(echo "$COMMIT_MSG" | tail -n +2) |
25 | 112 |
|
| 113 | + # Check subject length (72 chars) |
| 114 | + SUBJECT_MAX_LEN=72 |
| 115 | + if [ ${#SUBJECT} -gt ${SUBJECT_MAX_LEN} ]; then |
| 116 | + echo -e "${ERROR} Subject exceeds ${SUBJECT_MAX_LEN} characters:"\ |
| 117 | + "'${SUBJECT}'" >&2 |
26 | 118 |
|
27 |
| -for commited_file in $commit_files; do |
28 |
| - head $commited_file | grep -q "$current_year Arm" |
29 |
| - if [[ $? != 0 ]] |
30 |
| - then |
31 |
| - echo "Header in $commited_file did not contain '$current_year Arm'" |
32 |
| - failed_license_check=true |
33 |
| - else |
34 |
| - echo "$commited_file passed license check" |
35 |
| - fi |
| 119 | + FAILED=1 |
| 120 | + else |
| 121 | + echo -e "${SUCCESS} Commit message subject OK" |
| 122 | + fi |
| 123 | + |
| 124 | + # Check body line length (72 chars) |
| 125 | + BODY_MAX_LEN=72 |
| 126 | + line_number=2 # Subject + 1 empty line |
| 127 | + failed_body_check=false |
| 128 | + while IFS= read -r line; do |
| 129 | + if [ ${#line} -gt ${BODY_MAX_LEN} ]; then |
| 130 | + echo -e "${ERROR} Line ${line_number} in body exceeds"\ |
| 131 | + "${BODY_MAX_LEN} characters: '$line'" >&2 |
| 132 | + |
| 133 | + failed_body_check=true |
| 134 | + fi |
| 135 | + |
| 136 | + ((line_number++)) |
| 137 | + done <<< "$BODY" |
| 138 | + |
| 139 | + if [[ $failed_body_check == true ]]; then |
| 140 | + FAILED=1 |
| 141 | + else |
| 142 | + echo -e "${SUCCESS} Commit message body OK" |
| 143 | + fi |
| 144 | + |
| 145 | + # Check for Signed-off-by |
| 146 | + if ! echo "$COMMIT_MSG" | grep -qE "^Signed-off-by: "; then |
| 147 | + echo -e "${ERROR} Commit message must contain a 'Signed-off-by'"\ |
| 148 | + "footer." >&2 |
| 149 | + |
| 150 | + FAILED=1 |
| 151 | + fi |
| 152 | + |
| 153 | + # Check subject format, should start with 'Arm backend: ' and be |
| 154 | + # imperative mood. |
| 155 | + if [[ ! "$SUBJECT" =~ ^"Arm backend":\ (${VERBS}) ]]; then |
| 156 | + echo -e "${WARNING} Subject should start with 'Arm backend: '"\ |
| 157 | + "followed by an imperative verb." >&2 |
| 158 | + echo -n "There are warnings in your commit message. Do you want to"\ |
| 159 | + "ignore the warning (y/N): " > /dev/tty |
| 160 | + |
| 161 | + read USER_INPUT < /dev/tty |
| 162 | + |
| 163 | + # Check user input for warnings |
| 164 | + if [[ ! "$USER_INPUT" =~ ^[Yy]$ ]]; then |
| 165 | + FAILED=1 |
| 166 | + fi |
| 167 | + fi |
| 168 | + |
| 169 | + echo "" # Newline to visually separate commit processing |
36 | 170 | done
|
37 | 171 |
|
38 |
| -if [[ $failed_license_check == true ]] |
39 |
| - then |
40 |
| - exit 1 |
41 |
| - else |
42 |
| - echo "Passed simple license check" |
| 172 | +if [[ $FAILED ]]; then |
| 173 | + echo -e "${INFO} Fix your commit message errors with"\ |
| 174 | + "'git commit --amend' or 'git commit --fixup=<SHA>'" |
| 175 | + |
| 176 | + exit 1 |
| 177 | +else |
| 178 | + echo -e "${SUCCESS} All checks passed" |
43 | 179 | fi
|
44 | 180 |
|
45 | 181 | exit 0
|
0 commit comments