formatting.sh 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #!/usr/bin/env bash
  2. # YAPF formatter, adapted from ray and skypilot.
  3. #
  4. # Usage:
  5. # # Do work and commit your work.
  6. # # Format files that differ from origin/main.
  7. # bash format.sh
  8. # # Commit changed files with message 'Run yapf and pylint'
  9. #
  10. #
  11. # YAPF + Clang formatter (if installed). This script formats all changed files from the last mergebase.
  12. # You are encouraged to run this locally before pushing changes for review.
  13. # Cause the script to exit if a single command fails
  14. set -eo pipefail
  15. # this stops git rev-parse from failing if we run this from the .git directory
  16. builtin cd "$(dirname "${BASH_SOURCE:-$0}")"
  17. ROOT="$(git rev-parse --show-toplevel)"
  18. builtin cd "$ROOT" || exit 1
  19. YAPF_VERSION=$(yapf --version | awk '{print $2}')
  20. PYLINT_VERSION=$(pylint --version | head -n 1 | awk '{print $2}')
  21. MYPY_VERSION=$(mypy --version | awk '{print $2}')
  22. # # params: tool name, tool version, required version
  23. tool_version_check() {
  24. if [[ $2 != $3 ]]; then
  25. echo "Wrong $1 version installed: $3 is required, not $2."
  26. exit 1
  27. fi
  28. }
  29. tool_version_check "yapf" $YAPF_VERSION "$(grep yapf requirements-dev.txt | cut -d'=' -f3)"
  30. tool_version_check "pylint" $PYLINT_VERSION "$(grep "pylint==" requirements-dev.txt | cut -d'=' -f3)"
  31. tool_version_check "mypy" "$MYPY_VERSION" "$(grep mypy requirements-dev.txt | cut -d'=' -f3)"
  32. YAPF_FLAGS=(
  33. '--recursive'
  34. '--parallel'
  35. )
  36. YAPF_EXCLUDES=(
  37. '--exclude' 'build/**'
  38. )
  39. # Format specified files
  40. format() {
  41. yapf --in-place "${YAPF_FLAGS[@]}" "$@"
  42. }
  43. # Format files that differ from main branch. Ignores dirs that are not slated
  44. # for autoformat yet.
  45. format_changed() {
  46. # The `if` guard ensures that the list of filenames is not empty, which
  47. # could cause yapf to receive 0 positional arguments, making it hang
  48. # waiting for STDIN.
  49. #
  50. # `diff-filter=ACM` and $MERGEBASE is to ensure we only format files that
  51. # exist on both branches.
  52. MERGEBASE="$(git merge-base origin/main HEAD)"
  53. if ! git diff --diff-filter=ACM --quiet --exit-code "$MERGEBASE" -- '*.py' '*.pyi' &>/dev/null; then
  54. git diff --name-only --diff-filter=ACM "$MERGEBASE" -- '*.py' '*.pyi' | xargs -P 5 \
  55. yapf --in-place "${YAPF_EXCLUDES[@]}" "${YAPF_FLAGS[@]}"
  56. fi
  57. }
  58. # Format all files
  59. format_all() {
  60. yapf --in-place "${YAPF_FLAGS[@]}" "${YAPF_EXCLUDES[@]}" aphrodite tests
  61. }
  62. ## This flag formats individual files. --files *must* be the first command line
  63. ## arg to use this option.
  64. if [[ "$1" == '--files' ]]; then
  65. format "${@:2}"
  66. # If `--all` is passed, then any further arguments are ignored and the
  67. # entire python directory is formatted.
  68. elif [[ "$1" == '--all' ]]; then
  69. format_all
  70. else
  71. # Format only the files that changed in last commit.
  72. format_changed
  73. fi
  74. echo 'Aphrodite Engine yapf: Done'
  75. # Run Pylint
  76. echo 'Aphrodite Engine Pylint:'
  77. pylint aphrodite tests
  78. if ! git diff --quiet &>/dev/null; then
  79. echo 'Reformatted files. Please review and stage the changes.'
  80. echo 'Changes not staged for commit:'
  81. echo
  82. git --no-pager diff --name-only
  83. exit 1
  84. fi