Skip to content

Commit 332008c

Browse files
clang-tidy environmental consistency (#109)
* Consistent clang-tidy.sh script * Fixes all remaining warnings * Treat warnings as errors for CI purposes/not building tech debt
1 parent c15ad7b commit 332008c

30 files changed

Lines changed: 905 additions & 227 deletions

.clang-tidy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Checks: >
99
-bugprone-easily-swappable-parameters,
1010
-modernize-use-trailing-return-type,
1111
-modernize-avoid-c-arrays,
12+
-modernize-type-traits,
1213
-modernize-use-auto,
1314
-modernize-use-nodiscard,
1415
-modernize-return-braced-init-list,
@@ -29,7 +30,8 @@ WarningsAsErrors: >
2930
bugprone-string-literal-with-embedded-nul,
3031
bugprone-suspicious-memset-usage,
3132
32-
HeaderFilterRegex: '(include/livekit|src|examples)'
33+
HeaderFilterRegex: '.*/(include/livekit|src)/.*\.(h|hpp)$'
34+
ExcludeHeaderFilterRegex: '(.*/src/tests/.*)|(.*/_deps/.*)|(.*/build-[^/]*/.*)'
3335

3436
FormatStyle: file
3537

.github/workflows/builds.yml

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,6 @@ jobs:
553553
continue-on-error: false
554554
permissions:
555555
contents: read
556-
pull-requests: write
557556

558557
steps:
559558
- name: Checkout (with submodules)
@@ -568,8 +567,28 @@ jobs:
568567
sudo apt-get update
569568
sudo apt-get install -y \
570569
build-essential cmake ninja-build pkg-config \
571-
llvm-dev libclang-dev clang clang-tidy \
572-
libssl-dev
570+
llvm-dev libclang-dev clang \
571+
libssl-dev wget ca-certificates gnupg
572+
573+
- name: Install clang-tidy 19 (for ExcludeHeaderFilterRegex support)
574+
run: |
575+
set -eux
576+
# Ubuntu 24.04 apt ships clang-tidy 18, which doesn't understand
577+
# ExcludeHeaderFilterRegex (added in 19). Pull clang-tidy 19 from
578+
# the upstream LLVM apt repository and pin the unversioned names.
579+
sudo install -m 0755 -d /etc/apt/keyrings
580+
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key \
581+
| sudo tee /etc/apt/keyrings/llvm.asc >/dev/null
582+
sudo chmod a+r /etc/apt/keyrings/llvm.asc
583+
codename=$(lsb_release -cs)
584+
echo "deb [signed-by=/etc/apt/keyrings/llvm.asc] http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-19 main" \
585+
| sudo tee /etc/apt/sources.list.d/llvm-19.list >/dev/null
586+
sudo apt-get update
587+
sudo apt-get install -y clang-tidy-19 clang-tools-19
588+
sudo ln -sf /usr/bin/clang-tidy-19 /usr/local/bin/clang-tidy
589+
sudo ln -sf /usr/bin/run-clang-tidy-19 /usr/local/bin/run-clang-tidy
590+
clang-tidy --version
591+
run-clang-tidy --help | head -1 || true
573592
574593
- name: Install Rust (stable)
575594
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
@@ -590,33 +609,9 @@ jobs:
590609
run: cmake --build build-release --target livekit_proto
591610

592611
- name: Run clang-tidy
593-
uses: cpp-linter/cpp-linter-action@77c390c5ba9c947ebc185a3e49cc754f1558abb5 # v2.18.0
594-
id: linter
595612
env:
596-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
597-
with:
598-
style: ''
599-
tidy-checks: ''
600-
database: build-release
601-
files-changed-only: false
602-
lines-changed-only: true
603-
extensions: 'c,cpp,cc,cxx'
604-
ignore: 'build-*|cpp-example-collection|client-sdk-rust|vcpkg_installed|src/tests|bridge|src/room_event_converter.cpp'
605-
file-annotations: true
606-
thread-comments: false
607-
step-summary: true
608-
tidy-review: false
609-
no-lgtm: true
610-
jobs: 0 # 0 == use all available CPU cores
611-
612-
- name: Check warning thresholds
613-
env:
614-
TIDY_FINDINGS: ${{ steps.linter.outputs.clang-tidy-checks-failed }}
615-
MAX_TIDY_FINDINGS: '0'
616-
run: |
617-
echo "clang-tidy findings: ${TIDY_FINDINGS}"
618-
if [ "${TIDY_FINDINGS}" -gt "${MAX_TIDY_FINDINGS}" ]; then
619-
echo "::warning::clang-tidy found ${TIDY_FINDINGS} issue(s), threshold is ${MAX_TIDY_FINDINGS}"
620-
exit 1
621-
fi
622-
echo "clang-tidy findings within threshold"
613+
TIDY_BLOB_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
614+
# This script is intended to be run locally and in CI. It will auto-detect
615+
# the GHA environment and add PR annotations and a run summary.
616+
# As of writing all warnings are treateded as errors to avoid tech debt build up
617+
run: ./scripts/clang-tidy.sh --fail-on-warning

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ lib/
3030
*.dylib
3131
*.dll
3232
*.exe
33-
livekit.log
33+
*.log
3434
web/
3535
*trace.json
3636
compile_commands.json

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Be sure to update the directory layout in this file if the directory layout chan
7979
| `client-sdk-rust/livekit-ffi/protocol/*.proto` | FFI contract (protobuf definitions, read-only reference) |
8080
| `cmake/` | Build helpers (`protobuf.cmake`, `spdlog.cmake`, `LiveKitConfig.cmake.in`) |
8181
| `docker/` | Dockerfile for CI and SDK distribution images |
82+
| `scripts/` | Developer / CI helper scripts (e.g. `clang-tidy.sh`) |
8283
| `.github/workflows/` | GitHub Actions CI workflows |
8384

8485
### Key Types

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,13 +522,28 @@ sudo apt-get install clang-format clang-tidy clang-tools
522522

523523
To run:
524524

525-
1. Run a build script command, such that `compile_command.json` is present at the root of the repository
526-
2. Run:
525+
1. Generate `compile_commands.json` and the protobuf headers via a release build:
527526

528527
```bash
529-
clang-tidy -p . src/*.cpp
528+
./build.sh release
530529
```
531530

531+
1. Run the clang-tidy wrapper, which uses the same file set, regex filters, and `.clang-tidy` config as CI:
532+
533+
```bash
534+
./scripts/clang-tidy.sh
535+
```
536+
537+
The wrapper forwards extra arguments to `run-clang-tidy`, examples below:
538+
539+
```bash
540+
./scripts/clang-tidy.sh -j 4 # Change number of cores used
541+
./scripts/clang-tidy.sh -checks='-*,misc-const-correctness' # Only run certain checks
542+
./scripts/clang-tidy.sh -fix # Apply fixes automatically
543+
```
544+
545+
Output is captured to `clang-tidy.log` at the repo root. This is done as a convenience feature, as often times the terminal buffer is not large enough for all the output.
546+
532547
### Memory Checks
533548

534549
Run valgrind on various examples or tests to check for memory leaks and other issues.

include/livekit/audio_stream.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ class FfiEvent;
4141
* This struct wraps an AudioFrame and is used as the output type when
4242
* reading from an AudioStream.
4343
*/
44+
// NOLINTBEGIN(bugprone-exception-escape)
45+
// AudioFrame can throw in various places monitored by bugprone-exception-escape
46+
// Suppressing for now, would require significant refactor to fix
4447
struct AudioFrameEvent {
4548
AudioFrame frame; ///< The decoded PCM audio frame.
4649
};
50+
// NOLINTEND(bugprone-exception-escape)
4751

4852
/**
4953
* Represents a pull-based stream of decoded PCM audio frames coming from

include/livekit/local_track_publication.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,11 @@ namespace proto {
2424
class OwnedTrackPublication;
2525
}
2626

27-
class Track;
28-
2927
class LocalTrackPublication : public TrackPublication {
3028
public:
3129
/// Note, this LocalTrackPublication is constructed internally only;
3230
/// safe to accept proto::OwnedTrackPublication.
3331
explicit LocalTrackPublication(const proto::OwnedTrackPublication &owned);
34-
35-
/// Typed accessor for the attached LocalTrack (if any).
36-
std::shared_ptr<Track> track() const noexcept;
3732
};
3833

3934
} // namespace livekit

include/livekit/remote_track_publication.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,12 @@ namespace proto {
2424
class OwnedTrackPublication;
2525
}
2626

27-
class Track;
28-
2927
class RemoteTrackPublication : public TrackPublication {
3028
public:
3129
/// Note, this RemoteTrackPublication is constructed internally only;
3230
/// safe to accept proto::OwnedTrackPublication.
3331
explicit RemoteTrackPublication(const proto::OwnedTrackPublication &owned);
34-
35-
/// Typed accessor for the attached RemoteTrack (if any).
36-
std::shared_ptr<Track> track() const noexcept;
37-
32+
3833
bool subscribed() const noexcept { return subscribed_; }
3934

4035
void setSubscribed(bool subscribed);

include/livekit/result.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,49 +64,62 @@ template <typename T, typename E> class [[nodiscard]] Result {
6464
/// Allows `if (result)` style success checks.
6565
explicit operator bool() const noexcept { return ok(); }
6666

67+
// TODO (AEG): clang-tidy flagged these accessors because the signatures are marked
68+
// noexcept, but std::get can throw a std::bad_variant_access exception on
69+
// std::variant specifically. Investigate if this is actually a concern or if the types
70+
// are safe within this class (unit test ideal).
71+
6772
/// Access the success value. Requires `ok() == true`.
73+
// NOLINTNEXTLINE(bugprone-exception-escape)
6874
T &value() & noexcept {
6975
assert(ok());
7076
return std::get<0>(storage_);
7177
}
7278

7379
/// Access the success value. Requires `ok() == true`.
80+
// NOLINTNEXTLINE(bugprone-exception-escape)
7481
const T &value() const & noexcept {
7582
assert(ok());
7683
return std::get<0>(storage_);
7784
}
7885

7986
/// Move the success value out. Requires `ok() == true`.
87+
// NOLINTNEXTLINE(bugprone-exception-escape)
8088
T &&value() && noexcept {
8189
assert(ok());
8290
return std::get<0>(std::move(storage_));
8391
}
8492

8593
/// Move the success value out. Requires `ok() == true`.
94+
// NOLINTNEXTLINE(bugprone-exception-escape)
8695
const T &&value() const && noexcept {
8796
assert(ok());
8897
return std::get<0>(std::move(storage_));
8998
}
9099

91100
/// Access the error value. Requires `has_error() == true`.
101+
// NOLINTNEXTLINE(bugprone-exception-escape)
92102
E &error() & noexcept {
93103
assert(has_error());
94104
return std::get<1>(storage_);
95105
}
96106

97107
/// Access the error value. Requires `has_error() == true`.
108+
// NOLINTNEXTLINE(bugprone-exception-escape)
98109
const E &error() const & noexcept {
99110
assert(has_error());
100111
return std::get<1>(storage_);
101112
}
102113

103114
/// Move the error value out. Requires `has_error() == true`.
115+
// NOLINTNEXTLINE(bugprone-exception-escape)
104116
E &&error() && noexcept {
105117
assert(has_error());
106118
return std::get<1>(std::move(storage_));
107119
}
108120

109121
/// Move the error value out. Requires `has_error() == true`.
122+
// NOLINTNEXTLINE(bugprone-exception-escape)
110123
const E &&error() const && noexcept {
111124
assert(has_error());
112125
return std::get<1>(std::move(storage_));

include/livekit/subscription_thread_dispatcher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class SubscriptionThreadDispatcher {
471471
active_readers_;
472472

473473
/// Next auto-increment ID for data frame callbacks.
474-
DataFrameCallbackId next_data_callback_id_;
474+
DataFrameCallbackId next_data_callback_id_{0};
475475

476476
/// Registered data frame callbacks keyed by opaque callback ID.
477477
std::unordered_map<DataFrameCallbackId, RegisteredDataCallback>

0 commit comments

Comments
 (0)