Skip to content

Commit 5da83ee

Browse files
committed
clang-tidy: discover binaries in build dir
This changes the clang-tidy script to discover binaries you've built locally without having to pass them. Differential Revision: https://reviews.llvm.org/D100692
1 parent 9504ab3 commit 5da83ee

File tree

1 file changed

+40
-32
lines changed

1 file changed

+40
-32
lines changed

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

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22
#
33
#===- run-clang-tidy.py - Parallel clang-tidy runner --------*- python -*--===#
44
#
@@ -41,6 +41,7 @@
4141
import json
4242
import multiprocessing
4343
import os
44+
import queue
4445
import re
4546
import shutil
4647
import subprocess
@@ -54,13 +55,6 @@
5455
except ImportError:
5556
yaml = None
5657

57-
is_py2 = sys.version[0] == '2'
58-
59-
if is_py2:
60-
import Queue as queue
61-
else:
62-
import queue as queue
63-
6458

6559
def strtobool(val):
6660
"""Convert a string representation of truth to a bool following LLVM's CLI argument parsing."""
@@ -158,20 +152,29 @@ def merge_replacement_files(tmpdir, mergefile):
158152
open(mergefile, 'w').close()
159153

160154

161-
def check_clang_apply_replacements_binary(args):
162-
"""Checks if invoking supplied clang-apply-replacements binary works."""
163-
try:
164-
subprocess.check_call([args.clang_apply_replacements_binary, '--version'])
165-
except:
166-
print('Unable to run clang-apply-replacements. Is clang-apply-replacements '
167-
'binary correctly specified?', file=sys.stderr)
168-
traceback.print_exc()
169-
sys.exit(1)
155+
def find_binary(arg, name, build_path):
156+
"""Get the path for a binary or exit"""
157+
if arg:
158+
if shutil.which(arg):
159+
return arg
160+
else:
161+
raise SystemExit(
162+
"error: passed binary '{}' was not found or is not executable"
163+
.format(arg))
164+
165+
built_path = os.path.join(build_path, "bin", name)
166+
binary = shutil.which(name) or shutil.which(built_path)
167+
if binary:
168+
return binary
169+
else:
170+
raise SystemExit(
171+
"error: failed to find {} in $PATH or at {}"
172+
.format(name, built_path))
170173

171174

172-
def apply_fixes(args, tmpdir):
175+
def apply_fixes(args, clang_apply_replacements_binary, tmpdir):
173176
"""Calls clang-apply-fixes on a given directory."""
174-
invocation = [args.clang_apply_replacements_binary]
177+
invocation = [clang_apply_replacements_binary]
175178
if args.format:
176179
invocation.append('-format')
177180
if args.style:
@@ -180,11 +183,12 @@ def apply_fixes(args, tmpdir):
180183
subprocess.call(invocation)
181184

182185

183-
def run_tidy(args, tmpdir, build_path, queue, lock, failed_files):
186+
def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock,
187+
failed_files):
184188
"""Takes filenames out of queue and runs clang-tidy on them."""
185189
while True:
186190
name = queue.get()
187-
invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks,
191+
invocation = get_tidy_invocation(name, clang_tidy_binary, args.checks,
188192
tmpdir, build_path, args.header_filter,
189193
args.allow_enabling_alpha_checkers,
190194
args.extra_arg, args.extra_arg_before,
@@ -210,15 +214,13 @@ def main():
210214
parser = argparse.ArgumentParser(description='Runs clang-tidy over all files '
211215
'in a compilation database. Requires '
212216
'clang-tidy and clang-apply-replacements in '
213-
'$PATH.')
217+
'$PATH or in your build directory.')
214218
parser.add_argument('-allow-enabling-alpha-checkers',
215219
action='store_true', help='allow alpha checkers from '
216220
'clang-analyzer.')
217221
parser.add_argument('-clang-tidy-binary', metavar='PATH',
218-
default='clang-tidy',
219222
help='path to clang-tidy binary')
220223
parser.add_argument('-clang-apply-replacements-binary', metavar='PATH',
221-
default='clang-apply-replacements',
222224
help='path to clang-apply-replacements binary')
223225
parser.add_argument('-checks', default=None,
224226
help='checks filter, when not specified, use clang-tidy '
@@ -278,8 +280,18 @@ def main():
278280
# Find our database
279281
build_path = find_compilation_database(db_path)
280282

283+
clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy",
284+
build_path)
285+
286+
tmpdir = None
287+
if args.fix or (yaml and args.export_fixes):
288+
clang_apply_replacements_binary = find_binary(
289+
args.clang_apply_replacements_binary, "clang-apply-replacements",
290+
build_path)
291+
tmpdir = tempfile.mkdtemp()
292+
281293
try:
282-
invocation = get_tidy_invocation("", args.clang_tidy_binary, args.checks,
294+
invocation = get_tidy_invocation("", clang_tidy_binary, args.checks,
283295
None, build_path, args.header_filter,
284296
args.allow_enabling_alpha_checkers,
285297
args.extra_arg, args.extra_arg_before,
@@ -306,11 +318,6 @@ def main():
306318
if max_task == 0:
307319
max_task = multiprocessing.cpu_count()
308320

309-
tmpdir = None
310-
if args.fix or (yaml and args.export_fixes):
311-
check_clang_apply_replacements_binary(args)
312-
tmpdir = tempfile.mkdtemp()
313-
314321
# Build up a big regexy filter from all command line arguments.
315322
file_name_re = re.compile('|'.join(args.files))
316323

@@ -323,7 +330,8 @@ def main():
323330
lock = threading.Lock()
324331
for _ in range(max_task):
325332
t = threading.Thread(target=run_tidy,
326-
args=(args, tmpdir, build_path, task_queue, lock, failed_files))
333+
args=(args, clang_tidy_binary, tmpdir, build_path,
334+
task_queue, lock, failed_files))
327335
t.daemon = True
328336
t.start()
329337

@@ -357,7 +365,7 @@ def main():
357365
if args.fix:
358366
print('Applying fixes ...')
359367
try:
360-
apply_fixes(args, tmpdir)
368+
apply_fixes(args, clang_apply_replacements_binary, tmpdir)
361369
except:
362370
print('Error applying fixes.\n', file=sys.stderr)
363371
traceback.print_exc()

0 commit comments

Comments
 (0)