- CI: build/validate use backone selftest + binary names, add lint.yml - make-*.mk: emit/install backone binaries, drop zerotier-one paths - doc/debian/ext.installfiles: backone manpages, service, init, te - rule-compiler: npm test runs test.js; attic world planet files - AGENTS.md repository guidelines, tools/lint.sh changed-lines gate - gitignore: /backone-selftest, *.gcno, *.gcda
60 lines
1.9 KiB
Bash
Executable File
60 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# clang-format gate. Whole repo has format debt (139/141 first-party files fail),
|
|
# so default mode checks only lines CHANGED vs base. --all checks whole files.
|
|
# Usage: tools/lint.sh [base-commit] | tools/lint.sh --all
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
CF="${CLANG_FORMAT:-$(command -v clang-format || true)}"
|
|
if [ -z "$CF" ]; then
|
|
echo "lint: clang-format not found (pip install clang-format)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
PATHSPEC=(
|
|
'*.cpp' '*.hpp' '*.h'
|
|
':(exclude)ext/*' ':(exclude)java/*' ':(exclude)rustybits/*'
|
|
':(exclude)windows/*' ':(exclude)attic/*'
|
|
)
|
|
|
|
fail=0
|
|
|
|
check() { # $1=file, rest=--lines args; empty args = whole file
|
|
local f=$1
|
|
shift
|
|
if ! "$CF" --dry-run --Werror "$@" "$f"; then
|
|
fail=1
|
|
fi
|
|
}
|
|
|
|
if [ "${1:-}" = "--all" ]; then
|
|
while IFS= read -r f; do check "$f"; done < <(git ls-files "${PATHSPEC[@]}")
|
|
else
|
|
base=${1:-}
|
|
if [ -z "$base" ]; then
|
|
base=$(git merge-base HEAD '@{upstream}' 2>/dev/null || echo HEAD~1)
|
|
fi
|
|
# tracked changed files: only changed line ranges (MR = modified/renamed content)
|
|
while IFS= read -r f; do
|
|
args=()
|
|
while IFS= read -r hunk; do
|
|
# new-side header is "+start,count" (git diff format), not "+start,end"
|
|
[[ $hunk =~ \+([0-9]+)(,([0-9]+))? ]] || continue
|
|
start=${BASH_REMATCH[1]}
|
|
count=${BASH_REMATCH[3]:-1}
|
|
end=$((start + count - 1))
|
|
if [ "$count" -eq 0 ]; then # deletion-only: nearest surviving line
|
|
start=$((start > 1 ? start - 1 : 1))
|
|
end=$start
|
|
fi
|
|
args+=(--lines="$start:$end")
|
|
done < <(git diff -U0 --no-color "$base" --diff-filter=ACMR -- "$f" | grep '^@@' || true)
|
|
[ ${#args[@]} -eq 0 ] && continue
|
|
check "$f" "${args[@]}"
|
|
done < <(git diff --name-only --diff-filter=ACMR "$base" -- "${PATHSPEC[@]}")
|
|
# untracked new files: whole file (no debt possible yet)
|
|
while IFS= read -r f; do check "$f"; done < <(git ls-files --others --exclude-standard "${PATHSPEC[@]}")
|
|
fi
|
|
|
|
exit $fail
|