chore(lint): add lint scripts and Makefile targets

v3.0-lint
Rene Cannao 1 month ago
parent 62dd15f7c9
commit 1f2f79fc97

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail
# Generate compile_commands.json by wrapping make with Bear.
# Usage: ./generate-compile-commands.sh <build-cmd>
BUILD_CMD=${1:-"make -j$(nproc)"}
if ! command -v bear >/dev/null 2>&1; then
echo "bear is required. Install it (e.g. apt install bear)" >&2
exit 1
fi
echo "Running: bear -- ${BUILD_CMD}"
rm -f compile_commands.json
bear -- ${BUILD_CMD}
echo "compile_commands.json generated"

@ -0,0 +1,38 @@
#!/usr/bin/env python3
import sys
import yaml
import os
"""
Simple normalizer for clang-tidy export-fixes YAML. Produces sorted text lines:
<file>:<line>: <check> - <message>
"""
if len(sys.argv) != 2:
print("Usage: normalize-clang-tidy.py <export-fixes.yaml>")
sys.exit(2)
path = sys.argv[1]
if not os.path.exists(path):
# No diagnostics
sys.exit(0)
data = yaml.safe_load(open(path))
diagnostics = []
for diag in data.get('Diagnostics', []):
msg = diag.get('DiagnosticMessage', {})
file = msg.get('FilePath', '<unknown>')
offset = msg.get('FileOffset', 0)
# Best effort to map offset to line
try:
with open(file, 'rb') as fh:
content = fh.read()
line_no = content[:offset].count(b"\n") + 1
except Exception:
line_no = 0
check = diag.get('CheckName', '')
message = msg.get('Message', '').strip()
diagnostics.append(f"{file}:{line_no}: {check} - {message}")
for l in sorted(set(diagnostics)):
print(l)

@ -0,0 +1,26 @@
#!/usr/bin/env python3
import sys
import re
import os
"""
Normalize cppcheck stderr output. Produce lines like:
<file>:<line>: <id> - <message>
"""
path = sys.argv[1] if len(sys.argv) > 1 else None
data = ''
if path and os.path.exists(path):
data = open(path).read()
else:
data = sys.stdin.read()
lines = []
for raw in data.splitlines():
# cppcheck prints: [path:line]: (id) message
m = re.match(r"\[(?P<file>[^:]+):(?P<line>\d+)\] (?P<id>[^:]+): (?P<msg>.*)", raw)
if m:
lines.append(f"{m.group('file')}:{m.group('line')}: {m.group('id').strip()} - {m.group('msg').strip()}")
for l in sorted(set(lines)):
print(l)

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
# Runs clang-tidy and cppcheck for the initial scope (lib/ and include/)
# Expectation: compile_commands.json exists in repo root (generated by generate-compile-commands.sh)
SCOPE_GLOB="lib/**/*.cpp include/**/*.h"
CLANG_TIDY_BIN=${CLANG_TIDY_BIN:-clang-tidy}
CPPCHECK_BIN=${CPPCHECK_BIN:-cppcheck}
if [ ! -f compile_commands.json ]; then
echo "compile_commands.json not found. Run scripts/lint/generate-compile-commands.sh first." >&2
exit 1
fi
mkdir -p lint
echo "Running clang-tidy..."
# Export fixes to a YAML file per run; list files explicitly from git to scope to lib/ and include/
FILES=$(git ls-files lib | tr '\n' ' ')
${CLANG_TIDY_BIN} -p . -checks='clang-analyzer-*,bugprone-*,performance-*,modernize-*,readability-*' --export-fixes=lint/clang-tidy-fixes.yaml ${FILES} || true
echo "Running cppcheck..."
${CPPCHECK_BIN} --enable=warning,performance,portability,style --std=c++17 --project=compile_commands.json --inline-suppr 2> lint/cppcheck-output.txt || true
echo "Normalizing outputs..."
python3 scripts/lint/normalize-clang-tidy.py lint/clang-tidy-fixes.yaml > lint/clang-tidy.txt || true
python3 scripts/lint/normalize-cppcheck.py lint/cppcheck-output.txt > lint/cppcheck.txt || true
echo "Local lint run complete. Reports written to lint/clang-tidy.txt and lint/cppcheck.txt"
Loading…
Cancel
Save