From eeccf2bc0d0ea7ad34b20bc77d13c25bbe16793b Mon Sep 17 00:00:00 2001 From: Megvii Engine Team Date: Thu, 19 Aug 2021 18:53:08 +0800 Subject: [PATCH] ci(check): add clang-format in check stage GitOrigin-RevId: 25c24d78563d250741db0a6b28b4522f5500a0f2 --- dnn/src/cuda/cub/.clang-format | 2 + tools/format.py | 118 +++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 dnn/src/cuda/cub/.clang-format create mode 100755 tools/format.py diff --git a/dnn/src/cuda/cub/.clang-format b/dnn/src/cuda/cub/.clang-format new file mode 100644 index 000000000..9d159247d --- /dev/null +++ b/dnn/src/cuda/cub/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: false diff --git a/tools/format.py b/tools/format.py new file mode 100755 index 000000000..ed1f222f6 --- /dev/null +++ b/tools/format.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# This file is part of MegBrain. +# Copyright (c) 2014-2021 Megvii Inc. All rights reserved. +import argparse +import os +import re +import subprocess +import tempfile +from functools import partial +from multiprocessing import Manager + +from tqdm.contrib.concurrent import process_map + +# change workspace to MegBrain root dir +os.chdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) + +failed_files = Manager().list() + + +def process_file(file, clang_format, write): + source = open(file, "r").read() + source = re.sub(r"MGB_DEFINE(?P(.|\n)*?)// +{", "class MGB_DEFINE\g{", source) + + result = subprocess.check_output( + [ + clang_format, + "-style=file", + "-verbose", + "-assume-filename={}".format(file), + # file, + ], + input=bytes(source.encode("utf-8")), + ) + + result = result.decode("utf-8") + result = re.sub(r"class MGB_DEFINE((.|\n)*?){", r"MGB_DEFINE\1// {", result) + + if write: + with tempfile.NamedTemporaryFile( + dir=os.path.dirname(file), delete=False + ) as tmp_file: + tmp_file.write(result.encode("utf-8")) + os.rename(tmp_file.name, file) + else: + ret_code = subprocess.run( + ["diff", "--color=always", file, "-"], input=bytes(result.encode("utf-8")), + ).returncode + + # man diff: 0 for same, 1 for different, 2 if trouble. + if ret_code == 2: + raise RuntimeError("format process (without overwrite) failed") + if ret_code != 0: + print(file) + global failed_files + failed_files.append(file) + + +def main(): + parser = argparse.ArgumentParser( + description="Format source files using clang-format, eg: `./tools/format.py src -w`. \ + Require clang-format version == 12.0", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + parser.add_argument( + "path", nargs="+", help="file name or path based on MegBrain root dir." + ) + parser.add_argument( + "-w", + "--write", + action="store_true", + help="use formatted file to replace original file.", + ) + parser.add_argument( + "--clang-format", + default=os.getenv("CLANG_FORMAT", "clang-format"), + help="clang-format executable name; it can also be " + "modified via the CLANG_FORMAT environment var", + ) + args = parser.parse_args() + + format_type = [".cpp", ".c", ".h", ".cu", ".cuh", ".inl"] + + def getfiles(path): + rst = [] + for p in os.listdir(path): + p = os.path.join(path, p) + if os.path.isdir(p): + rst += getfiles(p) + elif ( + os.path.isfile(p) + and not os.path.islink(p) + and os.path.splitext(p)[1] in format_type + ): + rst.append(p) + return rst + + files = [] + for path in args.path: + if os.path.isdir(path): + files += getfiles(path) + elif os.path.isfile(path): + files.append(path) + else: + raise ValueError("Invalid path {}".format(path)) + + process_map( + partial(process_file, clang_format=args.clang_format, write=args.write,), + files, + chunksize=10, + ) + + if failed_files: + raise RuntimeError("above files are not properly formatted!") + + +if __name__ == "__main__": + main() -- GitLab