run_local_format.sh 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/bin/bash
  2. set -euo pipefail
  3. # 本地一键 clang-format。
  4. # 默认行为:格式化仓库内受管源码(C/C++ 头源文件)。
  5. # 可选参数:
  6. # --check 仅检查,不修改文件(不符合时返回非 0)
  7. # --changed 仅处理当前改动文件(默认处理全部受管源码)
  8. scriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  9. cd "${scriptDir}"
  10. mode="write" # write | check
  11. scope="all" # all | changed
  12. while (($# > 0)); do
  13. case "$1" in
  14. --check)
  15. mode="check"
  16. ;;
  17. --changed)
  18. scope="changed"
  19. ;;
  20. -h | --help)
  21. echo "用法: bash ./run_local_format.sh [--check] [--changed]"
  22. exit 0
  23. ;;
  24. *)
  25. echo "[错误] 未知参数: $1"
  26. echo "用法: bash ./run_local_format.sh [--check] [--changed]"
  27. exit 2
  28. ;;
  29. esac
  30. shift
  31. done
  32. if command -v clang-format >/dev/null 2>&1; then
  33. formatter="clang-format"
  34. elif command -v clang-format-21 >/dev/null 2>&1; then
  35. formatter="clang-format-21"
  36. elif command -v clang-format-20 >/dev/null 2>&1; then
  37. formatter="clang-format-20"
  38. else
  39. echo "[错误] 未找到 clang-format,可执行文件名尝试过: clang-format / clang-format-21 / clang-format-20"
  40. exit 127
  41. fi
  42. allFiles=()
  43. if [[ "${scope}" == "all" ]]; then
  44. mapfile -d '' allFiles < <(git ls-files -z -- '*.c' '*.h' '*.cc' '*.cpp' '*.hpp')
  45. else
  46. mapfile -d '' allFiles < <(git diff --name-only -z -- '*.c' '*.h' '*.cc' '*.cpp' '*.hpp')
  47. fi
  48. files=()
  49. for f in "${allFiles[@]}"; do
  50. case "${f}" in
  51. test/externalModule/* | build/* | coverage/* | .xmake/* | test/fuzzer/corpus/*) ;;
  52. *)
  53. files+=("${f}")
  54. ;;
  55. esac
  56. done
  57. echo "===================================================="
  58. echo "本地格式化启动"
  59. echo " - formatter=${formatter}"
  60. echo " - mode=${mode}"
  61. echo " - scope=${scope}"
  62. echo " - files=${#files[@]}"
  63. echo "===================================================="
  64. if [[ ${#files[@]} -eq 0 ]]; then
  65. echo "[信息] 没有可处理的源码文件"
  66. exit 0
  67. fi
  68. if [[ "${mode}" == "check" ]]; then
  69. if printf '%s\0' "${files[@]}" | xargs -0 "${formatter}" --dry-run --Werror; then
  70. echo "[完成] clang-format 检查通过"
  71. else
  72. echo "[失败] 存在不符合 .clang-format 的文件,请执行: bash ./run_local_format.sh"
  73. exit 1
  74. fi
  75. else
  76. printf '%s\0' "${files[@]}" | xargs -0 "${formatter}" -i
  77. echo "[完成] clang-format 已应用到 ${#files[@]} 个文件"
  78. fi