From 84383eafe9acc3036925537d156befc8a553948b Mon Sep 17 00:00:00 2001 From: Jens Tirsvad Nielsen Date: Sun, 11 Oct 2026 16:36:48 +0800 Subject: [PATCH] Make every clang-tidy finding an error Task: MIL-007#4 --- CHANGELOG.md | 3 ++- guides/quality-checks-cpp.md | 2 +- tests/test_quality_workflows_cpp_csharp.py | 25 ++++++++++++++++++++++ tools/quality-checks-cpp.sh | 4 +++- wiki/QualityChecksCpp.da.md | 4 ++-- wiki/QualityChecksCpp.md | 2 +- wiki/QualityChecksCpp.ms.md | 4 ++-- 7 files changed, 36 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96f644e..c3ac383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,8 @@ Each release lists its changes in these groups, in this order: (inputs `clang-format-version`, `clang-tidy-version`), with the inputs `working-directory`, `std`, `compile-commands-dir` and `tools-ref`. The repository needs a `.clang-format`; without a `.clang-tidy` the checks - `clang-diagnostic-*` and `clang-analyzer-*` run. + `clang-diagnostic-*` and `clang-analyzer-*` run, and every clang-tidy finding + is an error (`--warnings-as-errors=*`). - Reusable workflow `quality-checks-csharp.yml` (ADR-0008): `dotnet format --verify-no-changes` and `dotnet build -warnaserror` on an exact .NET SDK 10 or later (input `dotnet-sdk-version`, default `10.0.401`), with the inputs diff --git a/guides/quality-checks-cpp.md b/guides/quality-checks-cpp.md index ce7ab82..f4f1f20 100644 --- a/guides/quality-checks-cpp.md +++ b/guides/quality-checks-cpp.md @@ -56,7 +56,7 @@ version of a tool is a new release of this repository, not a silent change. | Files | Tool | What it reports | | --- | --- | --- | | tracked `*.c`, `*.cc`, `*.cpp`, `*.cxx`, `*.h`, `*.hh`, `*.hpp`, `*.hxx` | `clang-format --dry-run -Werror` | formatting that differs from `.clang-format` | -| the same files | `clang-tidy` | findings of the checks of `.clang-tidy` (or of `clang-diagnostic-*` and `clang-analyzer-*` without one); `*.c` files are checked as C17, the other files as the C++ standard of `std` | +| the same files | `clang-tidy` | findings of the checks of `.clang-tidy` (or of `clang-diagnostic-*` and `clang-analyzer-*` without one); `*.c` files are checked as C17, the other files as the C++ standard of `std`; every finding is an error (`--warnings-as-errors=*`), so a warning fails the run | Untracked files are not checked. A repository without these files passes with a notice. There is no `cppcheck`: only an old version of it is available as a diff --git a/tests/test_quality_workflows_cpp_csharp.py b/tests/test_quality_workflows_cpp_csharp.py index d752fa9..f8b44c0 100644 --- a/tests/test_quality_workflows_cpp_csharp.py +++ b/tests/test_quality_workflows_cpp_csharp.py @@ -312,6 +312,31 @@ class TestCppRun: assert len(calls) == 2 assert not any("--checks=" in call for call in calls) + @pytest.mark.parametrize( + ("files", "extra", "tidy_calls"), + [ + (("a.cpp", "lib/c.c"), {}, 2), + (("a.cpp", ".clang-tidy"), {}, 1), + (("a.cpp", "build/compile_commands.json"), {"COMPILE_COMMANDS_DIR": "build"}, 1), + ], + ids=["no-clang-tidy-file", "clang-tidy-file", "compile-database"], + ) + def test_every_clang_tidy_call_treats_warnings_as_errors( + self, + repo: Path, + tmp_path: Path, + cpp_bin: Path, + files: tuple[str, ...], + extra: dict[str, str], + tidy_calls: int, + ) -> None: + add_files(repo, *files) + _, calls = self.run(repo, tmp_path, cpp_bin, **extra) + tidy = [c for c in calls if c.startswith("clang-tidy")] + assert len(tidy) == tidy_calls + assert all("--warnings-as-errors=*" in call for call in tidy) + assert "--warnings-as-errors" not in calls[0] and calls[0].startswith("clang-format") + def test_no_default_checks_when_a_clang_tidy_file_is_above_the_working_directory( self, repo: Path, diff --git a/tools/quality-checks-cpp.sh b/tools/quality-checks-cpp.sh index cdcf52e..45e093c 100644 --- a/tools/quality-checks-cpp.sh +++ b/tools/quality-checks-cpp.sh @@ -127,7 +127,9 @@ run_checks() { # Without a .clang-tidy, clang-tidy enables no check and refuses to run, so # the project gets the compiler diagnostics and the static analyzer. - local tidy_args=(--quiet) + # clang-tidy exits 0 on a warning, so every finding is made an error: a + # finding must fail the check, as a failing tool does for the other languages. + local tidy_args=(--quiet "--warnings-as-errors=*") if ! find_config_upwards .clang-tidy _clang-tidy; then tidy_args+=("--checks=${DEFAULT_TIDY_CHECKS}") fi diff --git a/wiki/QualityChecksCpp.da.md b/wiki/QualityChecksCpp.da.md index 496e337..52683d8 100644 --- a/wiki/QualityChecksCpp.da.md +++ b/wiki/QualityChecksCpp.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`QualityChecksCpp`](QualityChecksCpp). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -49,7 +49,7 @@ Henvis til workflowet ved major-tagget (`@v1`) eller et præcist tag, aldrig ved | Filer | Værktøj | Hvad det melder | | --- | --- | --- | | sporede `*.c`, `*.cc`, `*.cpp`, `*.cxx`, `*.h`, `*.hh`, `*.hpp`, `*.hxx` | `clang-format --dry-run -Werror` | formatering, der afviger fra `.clang-format` | -| de samme filer | `clang-tidy` | fund fra kontrollerne i `.clang-tidy` (eller fra `clang-diagnostic-*` og `clang-analyzer-*` uden en); `*.c`-filer kontrolleres som C17, de øvrige filer som C++-standarden i `std` | +| de samme filer | `clang-tidy` | fund fra kontrollerne i `.clang-tidy` (eller fra `clang-diagnostic-*` og `clang-analyzer-*` uden en); `*.c`-filer kontrolleres som C17, de øvrige filer som C++-standarden i `std`; hvert fund er en fejl (`--warnings-as-errors=*`), så en advarsel får kørslen til at fejle | Usporede filer kontrolleres ikke. Et repository uden disse filer består med en bemærkning. Der er ingen `cppcheck`: kun en gammel version findes som pakke, og gamle værktøjer køres ikke (ADR-0008). diff --git a/wiki/QualityChecksCpp.md b/wiki/QualityChecksCpp.md index 1ea0ffa..9aa14a9 100644 --- a/wiki/QualityChecksCpp.md +++ b/wiki/QualityChecksCpp.md @@ -62,7 +62,7 @@ version of a tool is a new release of this repository, not a silent change. | Files | Tool | What it reports | | --- | --- | --- | | tracked `*.c`, `*.cc`, `*.cpp`, `*.cxx`, `*.h`, `*.hh`, `*.hpp`, `*.hxx` | `clang-format --dry-run -Werror` | formatting that differs from `.clang-format` | -| the same files | `clang-tidy` | findings of the checks of `.clang-tidy` (or of `clang-diagnostic-*` and `clang-analyzer-*` without one); `*.c` files are checked as C17, the other files as the C++ standard of `std` | +| the same files | `clang-tidy` | findings of the checks of `.clang-tidy` (or of `clang-diagnostic-*` and `clang-analyzer-*` without one); `*.c` files are checked as C17, the other files as the C++ standard of `std`; every finding is an error (`--warnings-as-errors=*`), so a warning fails the run | Untracked files are not checked. A repository without these files passes with a notice. There is no `cppcheck`: only an old version of it is available as a diff --git a/wiki/QualityChecksCpp.ms.md b/wiki/QualityChecksCpp.ms.md index e91d6ce..8bad26b 100644 --- a/wiki/QualityChecksCpp.ms.md +++ b/wiki/QualityChecksCpp.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`QualityChecksCpp`](QualityChecksCpp). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -49,7 +49,7 @@ Rujuk aliran kerja pada tag major (`@v1`) atau pada tag tepat, jangan sekali-kal | Fail | Alat | Apa yang dilaporkan | | --- | --- | --- | | `*.c`, `*.cc`, `*.cpp`, `*.cxx`, `*.h`, `*.hh`, `*.hpp`, `*.hxx` yang dijejaki | `clang-format --dry-run -Werror` | pemformatan yang berbeza daripada `.clang-format` | -| fail yang sama | `clang-tidy` | dapatan semakan dalam `.clang-tidy` (atau `clang-diagnostic-*` dan `clang-analyzer-*` tanpanya); fail `*.c` disemak sebagai C17, fail lain sebagai piawaian C++ dalam `std` | +| fail yang sama | `clang-tidy` | dapatan semakan dalam `.clang-tidy` (atau `clang-diagnostic-*` dan `clang-analyzer-*` tanpanya); fail `*.c` disemak sebagai C17, fail lain sebagai piawaian C++ dalam `std`; setiap dapatan ialah ralat (`--warnings-as-errors=*`), jadi amaran menggagalkan larian | Fail yang tidak dijejaki tidak disemak. Repositori tanpa fail ini lulus dengan satu notis. Tiada `cppcheck`: hanya versi lama tersedia sebagai pakej, dan alat lama tidak dijalankan (ADR-0008).