Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Static analysis configuration.
#
# Curated for signal rather than coverage: every check enabled here is one
# whose findings are worth reading. Checks that fire constantly on idiomatic
# code are disabled outright instead of being silenced with NOLINT at each
# site, because a warning nobody acts on trains everyone to ignore the tool.
---
Checks: >
bugprone-*,
performance-*,
clang-analyzer-*,
misc-*,
modernize-use-nullptr,
modernize-use-override,
modernize-use-emplace,
modernize-loop-convert,
-bugprone-easily-swappable-parameters,
-bugprone-narrowing-conversions,
-bugprone-branch-clone,
-misc-non-private-member-variables-in-classes,
-misc-no-recursion,
-misc-include-cleaner,
-misc-use-anonymous-namespace,
-misc-const-correctness,
-clang-analyzer-optin.core.EnumCastOutOfRange,
-performance-enum-size,
-clang-analyzer-optin.performance.Padding

# The tree is clean under this configuration, so anything new is a
# regression and should fail the build rather than scroll past in a log.
#
# This makes HeaderFilterRegex load-bearing rather than cosmetic: any header
# the filter admits can fail the build, which is why the filter below names
# first-party directories explicitly instead of pattern-matching on "src" or
# "include". It also means a clang-tidy version bump can surface new findings
# — that is intended, and the fix is to address them, not to widen the filter.
WarningsAsErrors: '*'

# Only first-party headers.
#
# This must name the source subdirectories explicitly. The obvious pattern —
# matching any path containing "src" or "include" — also matches the
# FetchContent trees, because a dependency checked out to
# _deps/mbedtls-src/include/mbedtls/aes.h contains BOTH. Combined with
# WarningsAsErrors below, that turned every macro-parentheses finding in Mbed
# TLS, GLFW, and NFD into a build failure.
#
# There are no headers directly in src/, and the repository's include/
# directory is empty, so enumerating the four module directories covers all
# first-party headers and cannot match a dependency.
HeaderFilterRegex: '.*[/\\]src[/\\](capture|cli|core|ui)[/\\]'

# clang-tidy must not rewrite formatting; that belongs to the author.
FormatStyle: none

# Notes on the disabled checks above:
# performance-enum-size shrinking enum base types saves bytes that
# do not matter here and invites surprising
# implicit conversions.
# clang-analyzer-optin.performance.Padding
# advises reordering members by size. It is
# aimed at objects allocated in bulk; the
# class it fires on has exactly one instance,
# so it would trade a readable, logically
# grouped header for ~48 bytes.
# misc-const-correctness proposes const on nearly every local.
# misc-include-cleaner cannot see through the pinned third-party
# headers pulled in by FetchContent.

CheckOptions:
# NetProbe uses lowerCamelCase for functions and locals, m_ for members,
# and UpperCamelCase for types. Naming checks are not enabled above, but
# recording the convention here documents it for anyone who turns them on.
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.PrivateMemberPrefix
value: m_
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,55 @@ jobs:
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: ctest --test-dir build-asan -C RelWithDebInfo --output-on-failure

clang-tidy:
name: clang-tidy (static analysis)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y clang clang-tidy libpcap-dev libgl1-mesa-dev libgtk-3-dev pkg-config

# Ninja rather than the default generator: clang-tidy needs
# compile_commands.json, and configuring is enough to produce it
# (FetchContent populates its dependencies at configure time).
- name: Configure
env:
CC: clang
CXX: clang++
run: cmake -S . -B build-tidy -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF

# Analyse first-party sources only. Third-party code arrives through
# FetchContent and is not ours to fix; .clang-tidy's HeaderFilterRegex
# keeps their headers out of the report as well.
# Driving clang-tidy directly rather than through run-clang-tidy, which
# is packaged inconsistently across distributions.
#
# The pass/fail signal is the EXIT CODE, not the output. .clang-tidy
# sets WarningsAsErrors, so a finding fails the invocation; grepping the
# log for first-party paths instead would miss exactly the failures that
# matter, since a finding in a dependency header still fails the run.
- name: Run clang-tidy
run: |
clang-tidy --version
status=0
failed=""
while IFS= read -r file; do
echo "--- $file"
if ! clang-tidy -p build-tidy --quiet "$file"; then
status=1
failed="$failed $file"
fi
done < <(find src -name '*.cpp' | sort)
if [ "$status" -ne 0 ]; then
echo "::error::clang-tidy reported findings in:$failed"
fi
exit $status
shell: bash

fuzz:
name: Fuzz parser (60s)
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ Thumbs.db
# --- Agent Workspace Cache ---
/.agents/

# --- Local Planning Documents ---
# Implementation plans consumed by AI agents; not part of the shipped repo.
/plans/

# --- Demo Recording ---
/docs/record-demo.md

Expand Down
Loading
Loading