lint.sh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #! /bin/bash
  2. #
  3. # Linter script that checks for common style issues in Dolphin's codebase.
  4. set -euo pipefail
  5. # use Windows' git when working under path mounted from host on wsl2
  6. # inspired by https://markentier.tech/posts/2020/10/faster-git-under-wsl2/#solution
  7. GIT=git
  8. if [ "$(uname -s)" == "Linux" ]; then
  9. if [ "$(stat --file-system --format=%T `pwd -P`)" == "v9fs" ]; then
  10. GIT=git.exe
  11. fi
  12. fi
  13. if ! [ -x "$(command -v $GIT)" ]; then
  14. echo >&2 "error: git is not installed"
  15. exit 1
  16. fi
  17. REQUIRED_CLANG_FORMAT_MAJOR=13
  18. REQUIRED_CLANG_FORMAT_MINOR=0
  19. CLANG_FORMAT=clang-format
  20. CLANG_FORMAT_MAJOR=clang-format-${REQUIRED_CLANG_FORMAT_MAJOR}
  21. CLANG_FORMAT_MAJOR_MINOR=${CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}
  22. if [ -x "$(command -v $CLANG_FORMAT_MAJOR)" ]; then CLANG_FORMAT=$CLANG_FORMAT_MAJOR; fi
  23. if [ -x "$(command -v $CLANG_FORMAT_MAJOR_MINOR)" ]; then CLANG_FORMAT=$CLANG_FORMAT_MAJOR_MINOR; fi
  24. if ! [ -x "$(command -v $CLANG_FORMAT)" ]; then
  25. echo >&2 "error: clang-format is not installed"
  26. echo >&2 "Install clang-format version ${REQUIRED_CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}.*"
  27. exit 1
  28. fi
  29. FORCE=0
  30. if [ $# -gt 0 ]; then
  31. case "$1" in
  32. -f|--force)
  33. FORCE=1
  34. shift
  35. ;;
  36. esac
  37. fi
  38. if [ $FORCE -eq 0 ]; then
  39. CLANG_FORMAT_VERSION=$($CLANG_FORMAT --version)
  40. clang_format_version_ok=false
  41. clang_format_version_re='version ([0-9]+).([0-9]+)'
  42. if [[ $CLANG_FORMAT_VERSION =~ $clang_format_version_re ]]; then
  43. CLANG_FORMAT_MAJOR="${BASH_REMATCH[1]}"
  44. CLANG_FORMAT_MINOR="${BASH_REMATCH[2]}"
  45. if [ $CLANG_FORMAT_MAJOR == $REQUIRED_CLANG_FORMAT_MAJOR ] && [ $CLANG_FORMAT_MINOR == $REQUIRED_CLANG_FORMAT_MINOR ]; then
  46. clang_format_version_ok=true
  47. fi
  48. fi
  49. if ! [ "$clang_format_version_ok" = true ]; then
  50. echo >&2 "error: clang-format is the wrong version (${CLANG_FORMAT_VERSION})"
  51. echo >&2 "Install clang-format version ${REQUIRED_CLANG_FORMAT_MAJOR}.${REQUIRED_CLANG_FORMAT_MINOR}.* or use --force to ignore"
  52. exit 1
  53. fi
  54. fi
  55. did_java_setup=0
  56. JAVA_CODESTYLE_FILE="./$($GIT rev-parse --show-cdup)/Source/Android/code-style-java.xml"
  57. java_temp_dir=""
  58. function java_setup() {
  59. if [ "$did_java_setup" = 1 ]; then
  60. return
  61. fi
  62. if [ ! -x "${ANDROID_STUDIO_ROOT}/bin/format.sh" ]; then
  63. echo >&2 "error: must set ANDROID_STUDIO_ROOT environment variable to the IDE installation directory (current: ${ANDROID_STUDIO_ROOT})"
  64. exit 1
  65. fi
  66. java_temp_dir="$(mktemp -d)"
  67. trap "{ rm -r ${java_temp_dir}; }" EXIT
  68. did_java_setup=1
  69. }
  70. fail=0
  71. # Default to staged files, unless a commit was passed.
  72. COMMIT=${1:---cached}
  73. # Get modified files (must be on own line for exit-code handling)
  74. modified_files=$($GIT diff --name-only --diff-filter=ACMRTUXB $COMMIT)
  75. function java_check() {
  76. "${ANDROID_STUDIO_ROOT}/bin/format.sh" -s "${JAVA_CODESTYLE_FILE}" -R "${java_temp_dir}" >/dev/null
  77. # ignore 'added'/'deleted' files, we copied only files of interest to the tmpdir
  78. d=$($GIT diff --diff-filter=ad . "${java_temp_dir}" || true)
  79. if ! [ -z "${d}" ]; then
  80. echo "!!! Java code is not compliant to coding style, here is the fix:"
  81. echo "${d}"
  82. fail=1
  83. fi
  84. }
  85. # Loop through each modified file.
  86. for f in ${modified_files}; do
  87. # Filter them.
  88. if echo "${f}" | grep -E -q "[.]java$"; then
  89. # Copy Java files to a temporary directory
  90. java_setup
  91. mkdir -p $(dirname "${java_temp_dir}/${f}")
  92. cp "${f}" "${java_temp_dir}/${f}"
  93. continue
  94. fi
  95. if ! echo "${f}" | grep -E -q "[.](cpp|h|mm)$"; then
  96. continue
  97. fi
  98. if ! echo "${f}" | grep -E -q "^Source"; then
  99. continue
  100. fi
  101. # Check for clang-format issues.
  102. d=$($CLANG_FORMAT ${f} | (diff -u "${f}" - || true))
  103. if ! [ -z "${d}" ]; then
  104. echo "!!! ${f} not compliant to coding style, here is the fix:"
  105. echo "${d}"
  106. fail=1
  107. fi
  108. # Check for newline at EOF.
  109. last_line="$(tail -c 1 ${f})"
  110. if [ -n "${last_line}" ]; then
  111. echo "!!! ${f} not compliant to coding style:"
  112. echo "Missing newline at end of file"
  113. fail=1
  114. fi
  115. done
  116. if [ "${did_java_setup}" = 1 ]; then
  117. java_check
  118. fi
  119. exit ${fail}