45 lines
1.6 KiB
Bash
Executable File
45 lines
1.6 KiB
Bash
Executable File
#!/bin/sh
|
||
# Shell lint for the install scripts. Two checks:
|
||
# 1. POSIX syntax (sh -n) for every .sh we ship.
|
||
# 2. $VAR or ${VAR} glued to a non-ASCII character, which macOS's /bin/sh
|
||
# (bash 3.2) reads as part of the variable name: "($X;…" is an unbound
|
||
# variable there even when X is set, and install.sh runs with set -u.
|
||
# Write ${X}與… — braces fix it.
|
||
# Run: make lint-sh
|
||
set -u
|
||
cd "$(dirname "$0")/../.." || exit 1
|
||
fail=0
|
||
|
||
for f in install.sh $(find deploy -name '*.sh' | sort); do
|
||
if sh -n "$f" 2>/tmp/anybot-sh-lint.log; then
|
||
printf ' ✓ %s\n' "$f"
|
||
else
|
||
printf ' ✗ %s\n' "$f"; sed 's/^/ /' /tmp/anybot-sh-lint.log; fail=1
|
||
fi
|
||
done
|
||
|
||
printf '\n'
|
||
python3 - <<'PY' || fail=1
|
||
import glob, re, os, sys
|
||
pat = re.compile(r'(?<![A-Za-z0-9_$\\])\$([A-Za-z_][A-Za-z0-9_]*)([^\x00-\x7f])')
|
||
root = os.getcwd()
|
||
files = []
|
||
for d, dirs, fs in os.walk('.'):
|
||
dirs[:] = [x for x in dirs if x not in ('target', '.git', 'node_modules')]
|
||
files += [os.path.join(d, x) for x in fs if x.endswith('.sh')]
|
||
bad = 0
|
||
for f in sorted(files):
|
||
for i, line in enumerate(open(f, encoding='utf-8'), 1):
|
||
if line.strip().startswith('#'):
|
||
continue
|
||
for m in pat.finditer(line):
|
||
print(f' ✗ {f}:{i}: ${m.group(1)}{m.group(2)} → 在 macOS 的 /bin/sh 是未設定變數(改用 ${{{m.group(1)}}}{m.group(2)})')
|
||
print(f' {line.strip()[:100]}')
|
||
bad += 1
|
||
print(' ✓ no $VAR glued to Chinese punctuation' if not bad else f' {bad} places to fix')
|
||
sys.exit(1 if bad else 0)
|
||
PY
|
||
|
||
[ "$fail" = 0 ] && printf '\n 都過了。\n' || printf '\n 有東西要修。\n'
|
||
exit $fail
|