Skip to content

Conversation

vbvictor
Copy link
Contributor

@vbvictor vbvictor commented Aug 19, 2025

Progress information bloated output, now run-clang-tidy emits only actual diagnostics, which makes reading its output significantly easier.

@llvmbot
Copy link
Member

llvmbot commented Aug 19, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: Baranov Victor (vbvictor)

Changes

Progress information bloated output, now run-clang-tidy emits only actual diagnostics, which makes reading its output significantly easier.


Full diff: https://github.com/llvm/llvm-project/pull/154416.diff

4 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py (+4-2)
  • (modified) clang-tools-extra/clang-tidy/tool/run-clang-tidy.py (+16-11)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (added) clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp (+24)
diff --git a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
index d7899e0a18d0c..bb012ceff442b 100755
--- a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
+++ b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
@@ -312,7 +312,8 @@ def main():
     if max_task_count == 0:
         max_task_count = multiprocessing.cpu_count()
     max_task_count = min(len(lines_by_file), max_task_count)
-    print(f"Running clang-tidy in {max_task_count} threads...")
+    if not args.quiet:
+        print(f"Running clang-tidy in {max_task_count} threads...")
 
     combine_fixes = False
     export_fixes_dir = None
@@ -408,7 +409,8 @@ def main():
         return_code = 1
 
     if combine_fixes:
-        print("Writing fixes to " + args.export_fixes + " ...")
+        if not args.quiet:
+            print("Writing fixes to " + args.export_fixes + " ...")
         try:
             merge_replacement_files(export_fixes_dir, args.export_fixes)
         except:
diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 670e0a2c7678a..69788b5b15b48 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -681,13 +681,14 @@ async def main() -> None:
     file_name_re = re.compile("|".join(args.files))
     files = {f for f in files if file_name_re.search(f)}
 
-    print(
-        f"Running clang-tidy in {max_task} threads for",
-        len(files),
-        "files out of",
-        number_files_in_database,
-        "in compilation database ...",
-    )
+    if not args.quiet:
+        print(
+            f"Running clang-tidy in {max_task} threads for",
+            len(files),
+            "files out of",
+            number_files_in_database,
+            "in compilation database ...",
+        )
 
     returncode = 0
     semaphore = asyncio.Semaphore(max_task)
@@ -716,13 +717,15 @@ async def main() -> None:
                     result.stderr += f"{result.filename}: terminated by signal {-result.returncode}\n"
             progress = f"[{i + 1: >{len(f'{len(files)}')}}/{len(files)}]"
             runtime = f"[{result.elapsed:.1f}s]"
-            print(f"{progress}{runtime} {' '.join(result.invocation)}")
+            if not args.quiet:
+                print(f"{progress}{runtime} {' '.join(result.invocation)}")
             if result.stdout:
                 print(result.stdout, end=("" if result.stderr else "\n"))
             if result.stderr:
                 print(result.stderr)
     except asyncio.CancelledError:
-        print("\nCtrl-C detected, goodbye.")
+        if not args.quiet:
+            print("\nCtrl-C detected, goodbye.")
         for task in tasks:
             task.cancel()
         if delete_fixes_dir:
@@ -742,7 +745,8 @@ async def main() -> None:
             print("No profiling data found.")
 
     if combine_fixes:
-        print(f"Writing fixes to {args.export_fixes} ...")
+        if not args.quiet:
+            print(f"Writing fixes to {args.export_fixes} ...")
         try:
             assert export_fixes_dir
             merge_replacement_files(export_fixes_dir, args.export_fixes)
@@ -752,7 +756,8 @@ async def main() -> None:
             returncode = 1
 
     if args.fix:
-        print("Applying fixes ...")
+        if not args.quiet:
+            print("Applying fixes ...")
         try:
             assert export_fixes_dir
             apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 388979d9577ba..4473584e9fb26 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -122,6 +122,10 @@ Improvements to clang-tidy
 - Improved :program:`clang-tidy` option `-quiet` by suppressing diagnostic
   count messages.
 
+- Improved :program:`run-clang-tidy.py` and :program:`clang-tidy-diff.py` 
+  scripts to respect the `-quiet` option by suppressing progress and
+  informational messages.
+
 New checks
 ^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp
new file mode 100644
index 0000000000000..aec9356f3ad1f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %/t/test.cpp\",\"file\":\"%/t/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
+// RUN: echo "Checks: '-*,readability-magic-numbers'" > %t/.clang-tidy
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: cd "%t"
+
+// RUN: %run_clang_tidy -quiet "test.cpp" 2>&1 | FileCheck %s --check-prefix=CHECK-RUN-QUIET
+// CHECK-RUN-QUIET-NOT: Running clang-tidy in {{[1-9][0-9]*}} threads for
+// CHECK-RUN-QUIET-NOT: {{[0-9]+}} warning{{s?}} generated
+// CHECK-RUN-QUIET-NOT: [1/1]
+// CHECK-RUN-QUIET: 42 is a magic number;
+
+// REQUIRES: shell
+// RUN: sed 's/42/99/' %s > %t-diff.cpp
+
+// RUN: not diff -U0 %s %t-diff.cpp | %clang_tidy_diff -checks=-*,readability-magic-numbers -quiet -- -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-DIFF-QUIET
+// CHECK-DIFF-QUIET-NOT: Running clang-tidy in {{[1-9][0-9]*}} threads...
+// CHECK-DIFF-QUIET-NOT: {{[0-9]+}} warning{{s?}} generated
+// CHECK-DIFF-QUIET: 99 is a magic number;
+
+int main() {
+  int x = 42;
+}

@llvmbot
Copy link
Member

llvmbot commented Aug 19, 2025

@llvm/pr-subscribers-clang-tidy

Author: Baranov Victor (vbvictor)

Changes

Progress information bloated output, now run-clang-tidy emits only actual diagnostics, which makes reading its output significantly easier.


Full diff: https://github.com/llvm/llvm-project/pull/154416.diff

4 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py (+4-2)
  • (modified) clang-tools-extra/clang-tidy/tool/run-clang-tidy.py (+16-11)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
  • (added) clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp (+24)
diff --git a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
index d7899e0a18d0c..bb012ceff442b 100755
--- a/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
+++ b/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
@@ -312,7 +312,8 @@ def main():
     if max_task_count == 0:
         max_task_count = multiprocessing.cpu_count()
     max_task_count = min(len(lines_by_file), max_task_count)
-    print(f"Running clang-tidy in {max_task_count} threads...")
+    if not args.quiet:
+        print(f"Running clang-tidy in {max_task_count} threads...")
 
     combine_fixes = False
     export_fixes_dir = None
@@ -408,7 +409,8 @@ def main():
         return_code = 1
 
     if combine_fixes:
-        print("Writing fixes to " + args.export_fixes + " ...")
+        if not args.quiet:
+            print("Writing fixes to " + args.export_fixes + " ...")
         try:
             merge_replacement_files(export_fixes_dir, args.export_fixes)
         except:
diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 670e0a2c7678a..69788b5b15b48 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -681,13 +681,14 @@ async def main() -> None:
     file_name_re = re.compile("|".join(args.files))
     files = {f for f in files if file_name_re.search(f)}
 
-    print(
-        f"Running clang-tidy in {max_task} threads for",
-        len(files),
-        "files out of",
-        number_files_in_database,
-        "in compilation database ...",
-    )
+    if not args.quiet:
+        print(
+            f"Running clang-tidy in {max_task} threads for",
+            len(files),
+            "files out of",
+            number_files_in_database,
+            "in compilation database ...",
+        )
 
     returncode = 0
     semaphore = asyncio.Semaphore(max_task)
@@ -716,13 +717,15 @@ async def main() -> None:
                     result.stderr += f"{result.filename}: terminated by signal {-result.returncode}\n"
             progress = f"[{i + 1: >{len(f'{len(files)}')}}/{len(files)}]"
             runtime = f"[{result.elapsed:.1f}s]"
-            print(f"{progress}{runtime} {' '.join(result.invocation)}")
+            if not args.quiet:
+                print(f"{progress}{runtime} {' '.join(result.invocation)}")
             if result.stdout:
                 print(result.stdout, end=("" if result.stderr else "\n"))
             if result.stderr:
                 print(result.stderr)
     except asyncio.CancelledError:
-        print("\nCtrl-C detected, goodbye.")
+        if not args.quiet:
+            print("\nCtrl-C detected, goodbye.")
         for task in tasks:
             task.cancel()
         if delete_fixes_dir:
@@ -742,7 +745,8 @@ async def main() -> None:
             print("No profiling data found.")
 
     if combine_fixes:
-        print(f"Writing fixes to {args.export_fixes} ...")
+        if not args.quiet:
+            print(f"Writing fixes to {args.export_fixes} ...")
         try:
             assert export_fixes_dir
             merge_replacement_files(export_fixes_dir, args.export_fixes)
@@ -752,7 +756,8 @@ async def main() -> None:
             returncode = 1
 
     if args.fix:
-        print("Applying fixes ...")
+        if not args.quiet:
+            print("Applying fixes ...")
         try:
             assert export_fixes_dir
             apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 388979d9577ba..4473584e9fb26 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -122,6 +122,10 @@ Improvements to clang-tidy
 - Improved :program:`clang-tidy` option `-quiet` by suppressing diagnostic
   count messages.
 
+- Improved :program:`run-clang-tidy.py` and :program:`clang-tidy-diff.py` 
+  scripts to respect the `-quiet` option by suppressing progress and
+  informational messages.
+
 New checks
 ^^^^^^^^^^
 
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp
new file mode 100644
index 0000000000000..aec9356f3ad1f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/quiet-flag-scripts.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %/t/test.cpp\",\"file\":\"%/t/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
+// RUN: echo "Checks: '-*,readability-magic-numbers'" > %t/.clang-tidy
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: cd "%t"
+
+// RUN: %run_clang_tidy -quiet "test.cpp" 2>&1 | FileCheck %s --check-prefix=CHECK-RUN-QUIET
+// CHECK-RUN-QUIET-NOT: Running clang-tidy in {{[1-9][0-9]*}} threads for
+// CHECK-RUN-QUIET-NOT: {{[0-9]+}} warning{{s?}} generated
+// CHECK-RUN-QUIET-NOT: [1/1]
+// CHECK-RUN-QUIET: 42 is a magic number;
+
+// REQUIRES: shell
+// RUN: sed 's/42/99/' %s > %t-diff.cpp
+
+// RUN: not diff -U0 %s %t-diff.cpp | %clang_tidy_diff -checks=-*,readability-magic-numbers -quiet -- -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-DIFF-QUIET
+// CHECK-DIFF-QUIET-NOT: Running clang-tidy in {{[1-9][0-9]*}} threads...
+// CHECK-DIFF-QUIET-NOT: {{[0-9]+}} warning{{s?}} generated
+// CHECK-DIFF-QUIET: 99 is a magic number;
+
+int main() {
+  int x = 42;
+}

@vbvictor
Copy link
Contributor Author

To be exact, these countless messages are totally gone:

[ 47/446][22.8s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
64711 warnings generated.

[ 48/446][21.7s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
62350 warnings generated.

[ 49/446][21.5s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp
62186 warnings generated.

[ 50/446][23.7s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
63421 warnings generated.

[ 51/446][18.0s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp
62275 warnings generated.

[ 52/446][17.9s] /usr/bin/clang-tidy -p=build/ -quiet /home/victor/llvm/llvm-project/clang-tools-extra/clang-tidy/android/CloexecSocketCheck.cpp
62172 warnings generated.

@firewave
Copy link

I actually like the progress information (the rest not so much) and it might give an indication if it is stuck or still running. It also contains information (timing) to compare between runs and indicate which files are hot spots.

@vbvictor
Copy link
Contributor Author

I actually like the progress information (the rest not so much) and it might give an indication if it is stuck or still running. It also contains information (timing) to compare between runs and indicate which files are hot spots.

Then to separate -quiet in clang-tidy and scripts we can add --hide-progress flag to suppress timings and other information. I'm not sure about option name though.

@vbvictor vbvictor force-pushed the make-quiet-flag-affect-scripts branch from 9c92891 to dab1d21 Compare August 29, 2025 14:33
@vbvictor vbvictor changed the title [clang-tidy] Improve "-quiet" option in tidy-scripts by suppressing progress information [clang-tidy] Add new '-hide-progress' option to tidy-scripts for suppressing progress information Aug 29, 2025
@vbvictor
Copy link
Contributor Author

I actually like the progress information (the rest not so much) and it might give an indication if it is stuck or still running. It also contains information (timing) to compare between runs and indicate which files are hot spots.

I reworked my implementation by adding new "hide-progress" option to scripts.

@vbvictor
Copy link
Contributor Author

Ping @carlosgalvezp @HerrCai0907 @5chmidti @PiotrZSL for opinions. I believe we should not bloat scripts with many options but separating "quiet" from "progress" seem beneficial, hence new option is introduced.

vbvictor and others added 2 commits September 6, 2025 16:42
Co-authored-by: Victor Chernyakin <chernyakin.victor.j@outlook.com>
@vbvictor vbvictor force-pushed the make-quiet-flag-affect-scripts branch from 7a0ad78 to 76dc88a Compare September 6, 2025 13:43
@vbvictor vbvictor merged commit dc81dcf into llvm:main Sep 6, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants