Skip to content

Commit 62f26cc

Browse files
Arm backend: Improve pre-push hook
Now checks: * License header * Lintrunner * Commit message This is done for all commits that are not on the remote branch the current branch is tracking. Commit message checks are: * Subject limit is 72 characters * Subject should start with "Arm backend: " + an imperative verb * Body limit is 72 characters * Must contain Signed-off-by Lines can be shorter than 72, but unless it's a new paragraph each line should get to as close to 72 characters as possible. This is not checked by the hook. Signed-off-by: Sebastian Larsson <[email protected]> Change-Id: Ie99d1ba4603455ededc8a12b440058c8665ff66c Signed-off-by: Yufeng Shi <[email protected]>
1 parent 3600d4f commit 62f26cc

File tree

1 file changed

+165
-29
lines changed

1 file changed

+165
-29
lines changed

backends/arm/scripts/pre-push

Lines changed: 165 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,178 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

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
1660
fi
1761

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")
21109

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)
25112

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
26118

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
36170
done
37171

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"
43179
fi
44180

45181
exit 0

0 commit comments

Comments
 (0)