|
|
|
|
|
|
|
|
|
|
|
import argparse |
|
|
|
|
|
from typing_extensions import Protocol |
|
|
|
|
|
|
|
|
|
|
|
import yapf |
|
|
|
|
|
|
|
|
|
|
|
from . import paths, proc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FormatArguments(Protocol): |
|
|
|
|
|
check: bool |
|
|
|
|
|
cpp: bool |
|
|
|
|
|
py: bool |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def start() -> None: |
|
|
|
|
|
parser = argparse.ArgumentParser() |
|
|
|
|
|
parser.add_argument('--check', |
|
|
|
|
|
help='Check whether files need to be formatted, but do not modify them.', |
|
|
|
|
|
action='store_true') |
|
|
|
|
|
parser.add_argument('--no-cpp', help='Skip formatting/checking C++ files', action='store_false', dest='cpp') |
|
|
|
|
|
parser.add_argument('--no-py', help='Skip formatting/checking Python files', action='store_false', dest='py') |
|
|
|
|
|
args: FormatArguments = parser.parse_args() |
|
|
|
|
|
|
|
|
|
|
|
if args.cpp: |
|
|
|
|
|
format_cpp(args) |
|
|
|
|
|
if args.py: |
|
|
|
|
|
format_py(args) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def format_cpp(args: FormatArguments) -> None: |
|
|
|
|
|
src_dir = paths.PROJECT_ROOT / 'src' |
|
|
|
|
|
cpp_files = src_dir.glob('**/*.[hc]pp') |
|
|
|
|
|
cf_args: proc.CommandLine = [ |
|
|
|
|
|
('--dry-run', '--Werror') if args.check else (), |
|
|
|
|
|
'-i', # Modify files in-place |
|
|
|
|
|
'--verbose', |
|
|
|
|
|
] |
|
|
|
|
|
for cf_cand in ('clang-format-10', 'clang-format-9', 'clang-format-8', 'clang-format'): |
|
|
|
|
|
cf = paths.find_exe(cf_cand) |
|
|
|
|
|
if not cf: |
|
|
|
|
|
continue |
|
|
|
|
|
break |
|
|
|
|
|
else: |
|
|
|
|
|
raise RuntimeError('No clang-format executable found') |
|
|
|
|
|
|
|
|
|
|
|
print(f'Using clang-format: {cf_cand}') |
|
|
|
|
|
res = proc.run([cf, cf_args, cpp_files]) |
|
|
|
|
|
if res.returncode and args.check: |
|
|
|
|
|
raise RuntimeError('Format checks failed for one or more C++ files. (See above.)') |
|
|
|
|
|
if res.returncode: |
|
|
|
|
|
raise RuntimeError('Format execution failed. Check output above.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def format_py(args: FormatArguments) -> None: |
|
|
|
|
|
py_files = paths.TOOLS_DIR.rglob('*.py') |
|
|
|
|
|
rc = yapf.main( |
|
|
|
|
|
list(proc.flatten_cmd([ |
|
|
|
|
|
'--parallel', |
|
|
|
|
|
'--verbose', |
|
|
|
|
|
('--diff') if args.check else ('--in-place'), |
|
|
|
|
|
py_files, |
|
|
|
|
|
]))) |
|
|
|
|
|
if rc and args.check: |
|
|
|
|
|
raise RuntimeError('Format checks for one or more Python files. (See above.)') |
|
|
|
|
|
if rc: |
|
|
|
|
|
raise RuntimeError('Format execution failed for Python code. See above.') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
start() |