Skip to content

Commit 2456fa1

Browse files
committed
ci: enable check typos for commit
1 parent da2303c commit 2456fa1

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

.codespellrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
[codespell]
3+
skip = *.py
4+
ignore-regex = _
5+
ignore-words-list = ot

.gitlab-ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,18 @@ deploy_docs_production:
244244
DOCS_DEPLOY_SERVER: "$DOCS_PROD_SERVER"
245245
DOCS_DEPLOY_SERVER_USER: "$DOCS_PROD_SERVER_USER"
246246
DOCS_DEPLOY_URL_BASE: "https://docs.espressif.com/projects/esp-thread-br"
247+
248+
check_typos:
249+
image: $ESP_ENV_IMAGE
250+
stage: build
251+
script:
252+
- pip install codespell
253+
- git fetch origin main
254+
- |
255+
FILES=$(git diff --name-only origin/main...HEAD)
256+
echo "Change files: $FILES"
257+
if [ -n "$FILES" ]; then
258+
./tools/check_typos.sh $FILES
259+
fi
260+
tags:
261+
- build

tools/check_typos.sh

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/bin/bash
2+
3+
# Usage: tools/check_typos.sh [source_file_or_directory] ...
4+
5+
CODESPELL_SKIP_LIST=()
6+
ERROR_FOUND=0
7+
8+
parse_codespellrc_skips() {
9+
if [ -f .codespellrc ]; then
10+
local skip_files
11+
skip_files=$(grep -E "^skip\s*=" .codespellrc | cut -d '=' -f2 | tr -d ' ')
12+
IFS=',' read -ra CODESPELL_SKIP_LIST <<< "$skip_files"
13+
fi
14+
}
15+
16+
should_skip_file() {
17+
local file_path="$1"
18+
for pattern in "${CODESPELL_SKIP_LIST[@]}"; do
19+
if [[ "$file_path" == $pattern* ]]; then
20+
return 0
21+
fi
22+
done
23+
return 1
24+
}
25+
26+
process_file() {
27+
local SRC_FILE="$1"
28+
cat "$SRC_FILE" | \
29+
python3 -c "
30+
import sys, re
31+
ignore_directive = re.compile(r\"[^\w\s]\s*codespell:ignore\b\")
32+
def split_line(line):
33+
if ignore_directive.search(line):
34+
return line.rstrip()
35+
tokens = re.findall(r\"\b[\w']+\b\", line)
36+
result = []
37+
for token in tokens:
38+
if \"'\" in token:
39+
result.append(token)
40+
else:
41+
result.extend(re.findall(r\"\d+[a-zA-Z]+|[A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+\", token))
42+
return \" \".join(result)
43+
for line in sys.stdin:
44+
print(split_line(line))
45+
" | codespell --check-hidden --stdin-single-line -q 32 - 2>&1 | sed "s|^|$SRC_FILE: |"
46+
if [ "${PIPESTATUS[2]}" -ne 0 ]; then
47+
ERROR_FOUND=1
48+
fi
49+
}
50+
51+
is_valid_file() {
52+
local file="$1"
53+
54+
case "$file" in
55+
*.c|*.h|*.cpp|*.py|*.txt|*.md|*.yml|*.ini|*.json|*.sh|*.cmake) ;;
56+
*) return 1 ;;
57+
esac
58+
59+
if should_skip_file "$file"; then
60+
return 1
61+
fi
62+
63+
return 0
64+
}
65+
66+
process_directory() {
67+
local DIR="$1"
68+
local file
69+
70+
find "$DIR" -type f | while read -r file; do
71+
if is_valid_file "$file"; then
72+
process_file "$file"
73+
fi
74+
done
75+
}
76+
77+
main() {
78+
local TARGETS=("$@")
79+
80+
parse_codespellrc_skips
81+
82+
if [ "$#" -eq 0 ]; then
83+
TARGETS=(./components ./examples)
84+
fi
85+
86+
for TARGET in "${TARGETS[@]}"; do
87+
if [ -f "$TARGET" ]; then
88+
if is_valid_file "$TARGET"; then
89+
process_file "$TARGET"
90+
fi
91+
elif [ -d "$TARGET" ]; then
92+
process_directory "$TARGET"
93+
else
94+
echo "Warning: '$TARGET' is not a valid file or directory, skipping"
95+
fi
96+
done
97+
98+
if [ "$ERROR_FOUND" == "1" ]; then
99+
echo "Typos found"
100+
exit 1
101+
fi
102+
}
103+
104+
main "$@"

0 commit comments

Comments
 (0)