You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.1KB

  1. import argparse
  2. from typing_extensions import Protocol
  3. import yapf
  4. from . import paths, proc
  5. class FormatArguments(Protocol):
  6. check: bool
  7. cpp: bool
  8. py: bool
  9. def start() -> None:
  10. parser = argparse.ArgumentParser()
  11. parser.add_argument('--check',
  12. help='Check whether files need to be formatted, but do not modify them.',
  13. action='store_true')
  14. parser.add_argument('--no-cpp', help='Skip formatting/checking C++ files', action='store_false', dest='cpp')
  15. parser.add_argument('--no-py', help='Skip formatting/checking Python files', action='store_false', dest='py')
  16. args: FormatArguments = parser.parse_args()
  17. if args.cpp:
  18. format_cpp(args)
  19. if args.py:
  20. format_py(args)
  21. def format_cpp(args: FormatArguments) -> None:
  22. src_dir = paths.PROJECT_ROOT / 'src'
  23. cpp_files = src_dir.glob('**/*.[hc]pp')
  24. cf_args: proc.CommandLine = [
  25. ('--dry-run', '--Werror') if args.check else (),
  26. '-i', # Modify files in-place
  27. '--verbose',
  28. ]
  29. for cf_cand in ('clang-format-10', 'clang-format-9', 'clang-format-8', 'clang-format'):
  30. cf = paths.find_exe(cf_cand)
  31. if not cf:
  32. continue
  33. break
  34. else:
  35. raise RuntimeError('No clang-format executable found')
  36. print(f'Using clang-format: {cf_cand}')
  37. res = proc.run([cf, cf_args, cpp_files])
  38. if res.returncode and args.check:
  39. raise RuntimeError('Format checks failed for one or more C++ files. (See above.)')
  40. if res.returncode:
  41. raise RuntimeError('Format execution failed. Check output above.')
  42. def format_py(args: FormatArguments) -> None:
  43. py_files = paths.TOOLS_DIR.rglob('*.py')
  44. rc = yapf.main(
  45. list(proc.flatten_cmd([
  46. '--parallel',
  47. '--verbose',
  48. ('--diff') if args.check else ('--in-place'),
  49. py_files,
  50. ])))
  51. if rc and args.check:
  52. raise RuntimeError('Format checks for one or more Python files. (See above.)')
  53. if rc:
  54. raise RuntimeError('Format execution failed for Python code. See above.')
  55. if __name__ == "__main__":
  56. start()