blob: 0fe1edc467806c3cd1c2160581e1faf7c015fa0f [file] [log] [blame]
#!/usr/bin/env python3
# Clang Format Helper
# -------------------
#
# Copyright (c) 2023 The Khronos Group Inc.
# Copyright (c) 2023 Google LLC
#
# 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.
#
# This script retrieves the list of files to format from git and feeds it to
# clang-format. It requires the following environment variable:
#
# CTS_CLANG_PATH=/path/to/clang-format
#
# which should point to clang-format from llvm 16.0.4
#
# Usage: python3 run-clang-format.py
#
# -v: verbose output
import argparse
import multiprocessing
import os
import re
import sys
import time
from common import getFilesModifiedSinceLastCommit, runCommandAsync, waitAsyncCommand
def getClangFormat():
clang_format = os.environ.get('CTS_CLANG_FORMAT')
if clang_format is not None:
return clang_format
print('CTS_CLANG_FORMAT is not defined. Set this environment variable to path to clang_format')
if not sys.platform.startswith('linux'):
sys.exit(1)
print('Falling back to scripts/src_util/clang-format')
clang_format = os.path.join(os.path.dirname(__file__), "clang-format")
return clang_format
def runClangFormat(files, thread_count, verbose):
clang_format = getClangFormat()
processes = []
total = len(files)
so_far = 0
last_report_time = time.time()
for file in files:
so_far = so_far + 1
if verbose:
print('Formatting {}'.format(file))
elif last_report_time + 1 < time.time():
print('\rFormatting {}/{}'.format(so_far, total), end = '')
last_report_time = last_report_time + 1
# Make sure a maximum of thread_count processes are in flight
if len(processes) > thread_count:
waitAsyncCommand(*processes[0])
processes = processes[1:]
command = [clang_format, file, '-i']
processes.append((runCommandAsync(command), command))
for process in processes:
waitAsyncCommand(*process)
print('\rFormatted {} '.format(total))
def runClangFormatOnModifiedFiles(verbose):
files = getFilesModifiedSinceLastCommit()
# Only format files that can be formatted by clang-format.
pattern = (r'.*\.(cpp|hpp|c|h|m|mm|hh|inc|js|java|json)')
files = [file for file in files if re.match('^%s$' % pattern, file, re.IGNORECASE)]
files = [f for f in files if 'vulkancts/scripts/src' not in f.replace('\\', '/')]
files = [f for f in files if not re.match('.*external/openglcts/modules/runner/.*Mustpass.*\.hpp', f.replace('\\', '/'))]
thread_count = min(8, multiprocessing.cpu_count())
runClangFormat(files, thread_count, verbose)
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("-v", action="store_true", default=False, help="verbose")
args = parser.parse_args()
runClangFormatOnModifiedFiles(args.v)