#!/usr/bin/env python3 # Copyright 2017 gRPC authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import argparse import multiprocessing import os import subprocess import sys sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), "..", "run_tests", "python_utils" ) ) import jobset clang_tidy = os.environ.get("CLANG_TIDY", "clang-tidy") argp = argparse.ArgumentParser(description="Run clang-tidy against core") argp.add_argument("files", nargs="+", help="Files to tidy") argp.add_argument("--fix", dest="fix", action="store_true") argp.add_argument( "-j", "--jobs", type=int, default=multiprocessing.cpu_count(), help="Number of CPUs to use", ) argp.add_argument("--only-changed", dest="only_changed", action="store_true") argp.set_defaults(fix=False, only_changed=False) args = argp.parse_args() # Explicitly passing the .clang-tidy config by reading it. # This is required because source files in the compilation database are # in a different source tree so clang-tidy cannot find the right config file # by seeking their parent directories. with open(".clang-tidy") as f: config = f.read() cmdline = [ clang_tidy, "--config=" + config, ] if args.fix: cmdline.append("--fix-errors") if args.only_changed: orig_files = set(args.files) actual_files = [] output = subprocess.check_output( ["git", "diff", "upstream/master", "HEAD", "--name-only"] ) for line in output.decode("ascii").splitlines(False): if line in orig_files: print(("check: %s" % line)) actual_files.append(line) else: print(("skip: %s - not in the build" % line)) args.files = actual_files jobs = [] for filename in args.files: jobs.append( jobset.JobSpec( cmdline + [filename], shortname=filename, timeout_seconds=15 * 60, ) ) num_fails, res_set = jobset.run(jobs, maxjobs=args.jobs, quiet_success=True) sys.exit(num_fails)