diff --git a/scripts/run-clang-tidy.py b/scripts/run-clang-tidy.py new file mode 100755 index 0000000..52487a4 --- /dev/null +++ b/scripts/run-clang-tidy.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: BSD-3-Clause +from argparse import ArgumentParser +from pathlib import Path +from subprocess import run +from concurrent.futures import ThreadPoolExecutor +from sys import exit + +parser = ArgumentParser( + description = 'Light-weight wrapper around clang-tidy to enable `make clang-tidy` or ' + + '`ninja clang-tidy` to function properly', + allow_abbrev = False +) +parser.add_argument('-s', required = True, type = str, metavar = 'sourcePath', + dest = 'sourcePath', help = 'Path to the source directory to run clang-tidy in') +parser.add_argument('-p', type = str, metavar = 'buildPath', + dest = 'buildPath', help = 'Path to the build directory containing a compile_commands.json') +args = parser.parse_args() + +def globFiles(): + srcDir = Path(args.sourcePath) + paths = set(('src', 'upgrade')) + suffixes = set(('c', 'h')) + for path in paths: + for suffix in suffixes: + yield srcDir.glob('{}/**/*.{}'.format(path, suffix)) + +def gatherFiles(): + for fileGlob in globFiles(): + for file in fileGlob: + yield file + +extraArgs = [ + '-Isrc/target', '-Isrc', '-Isrc/include', '-Isrc/platforms/native', + '-Ilibopencm3/include', '-Isrc/platforms/stm32' +] +for i, arg in enumerate(extraArgs): + extraArgs[i] = f'--extra-arg={arg}' + +if args.buildPath is not None: + print(f'Adding build path "{args.buildPath}" to extraArgs') + extraArgs += ['-p', args.buildPath] + +futures = [] +returncode = 0 +with ThreadPoolExecutor() as pool: + for file in gatherFiles(): + futures.append(pool.submit(run, ['clang-tidy'] + extraArgs + [str(file)])) + returncode = max((future.result().returncode for future in futures)) +exit(returncode)