Skip to content

Commit bc74625

Browse files
authored
[clang-tidy] Add an option to exclude files not present in the compile database (#120348)
A change list may include files that are not part of the compile database, which can cause clang-tidy to fail (e.g., due to missing included headers). To prevent false negatives, we should allow to skip processing these files.
1 parent 99ab848 commit bc74625

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import tempfile
3636
import threading
3737
import traceback
38+
from pathlib import Path
3839

3940
try:
4041
import yaml
@@ -124,6 +125,23 @@ def merge_replacement_files(tmpdir, mergefile):
124125
open(mergefile, "w").close()
125126

126127

128+
def get_compiling_files(args):
129+
"""Read a compile_commands.json database and return a set of file paths"""
130+
current_dir = Path.cwd()
131+
compile_commands_json = (
132+
(current_dir / args.build_path) if args.build_path else current_dir
133+
)
134+
compile_commands_json = compile_commands_json / "compile_commands.json"
135+
files = set()
136+
with open(compile_commands_json) as db_file:
137+
db_json = json.load(db_file)
138+
for entry in db_json:
139+
if "file" not in entry:
140+
continue
141+
files.add(Path(entry["file"]))
142+
return files
143+
144+
127145
def main():
128146
parser = argparse.ArgumentParser(
129147
description="Run clang-tidy against changed files, and "
@@ -234,6 +252,13 @@ def main():
234252
action="store_true",
235253
help="Allow empty enabled checks.",
236254
)
255+
parser.add_argument(
256+
"-only-check-in-db",
257+
dest="skip_non_compiling",
258+
default=False,
259+
action="store_true",
260+
help="Only check files in the compilation database",
261+
)
237262

238263
clang_tidy_args = []
239264
argv = sys.argv[1:]
@@ -243,11 +268,13 @@ def main():
243268

244269
args = parser.parse_args(argv)
245270

271+
compiling_files = get_compiling_files(args) if args.skip_non_compiling else None
272+
246273
# Extract changed lines for each file.
247274
filename = None
248275
lines_by_file = {}
249276
for line in sys.stdin:
250-
match = re.search('^\\+\\+\\+\\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
277+
match = re.search(r'^\+\+\+\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
251278
if match:
252279
filename = match.group(2)
253280
if filename is None:
@@ -260,6 +287,13 @@ def main():
260287
if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
261288
continue
262289

290+
# Skip any files not in the compiling list
291+
if (
292+
compiling_files is not None
293+
and (Path.cwd() / filename) not in compiling_files
294+
):
295+
continue
296+
263297
match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line)
264298
if match:
265299
start_line = int(match.group(1))

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ Improvements to clang-query
108108
Improvements to clang-tidy
109109
--------------------------
110110

111+
- Improved :program:`clang-tidy-diff.py` script. Add the `-only-check-in-db`
112+
option to exclude files not present in the compilation database, avoiding
113+
false-negative results.
114+
111115
- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
112116
happening on certain platforms when interrupting the script.
113117

0 commit comments

Comments
 (0)