format.sh 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/bin/env bash
  2. # Format all source files, or check them with --check.
  3. set -euo pipefail
  4. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  5. PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
  6. EXPECTED_CLANG_FORMAT_VERSION="${EXPECTED_CLANG_FORMAT_VERSION:-22.1.4}"
  7. cd "$PROJECT_DIR"
  8. MODE="format"
  9. if [[ "${1:-}" == "--check" ]]; then
  10. MODE="check"
  11. elif [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  12. echo "Usage: scripts/format.sh [--check]"
  13. exit 0
  14. elif [[ $# -gt 0 ]]; then
  15. echo "Unknown argument: $1" >&2
  16. echo "Usage: scripts/format.sh [--check]" >&2
  17. exit 1
  18. fi
  19. resolve_candidate() {
  20. local candidate="$1"
  21. if [[ "$candidate" == */* ]]; then
  22. [[ -x "$candidate" ]] && printf '%s\n' "$candidate"
  23. elif command -v "$candidate" >/dev/null 2>&1; then
  24. command -v "$candidate"
  25. fi
  26. }
  27. format_version() {
  28. "$1" --version | sed -E 's/.*version ([0-9]+(\.[0-9]+)*).*/\1/'
  29. }
  30. candidates=()
  31. if [[ -n "${CLANG_FORMAT:-}" ]]; then
  32. candidates+=("$CLANG_FORMAT")
  33. else
  34. candidates+=(
  35. "clang-format"
  36. "$HOME/.local/bin/clang-format"
  37. "clang-format-22"
  38. "/opt/homebrew/opt/llvm/bin/clang-format"
  39. "/usr/local/opt/llvm/bin/clang-format"
  40. "/opt/homebrew/opt/llvm@22/bin/clang-format"
  41. "/usr/local/opt/llvm@22/bin/clang-format"
  42. )
  43. fi
  44. CLANG_FORMAT_BIN=""
  45. for candidate in "${candidates[@]}"; do
  46. resolved="$(resolve_candidate "$candidate" || true)"
  47. if [[ -n "$resolved" &&
  48. "$(format_version "$resolved")" == "$EXPECTED_CLANG_FORMAT_VERSION" ]]; then
  49. CLANG_FORMAT_BIN="$resolved"
  50. break
  51. fi
  52. done
  53. if [[ -z "$CLANG_FORMAT_BIN" ]]; then
  54. echo "Error: clang-format ${EXPECTED_CLANG_FORMAT_VERSION} is required." >&2
  55. echo "" >&2
  56. echo "Install it with:" >&2
  57. echo " python3 -m pip install --user -r requirements-dev.txt" >&2
  58. echo "" >&2
  59. echo "Or set CLANG_FORMAT=/path/to/clang-format-${EXPECTED_CLANG_FORMAT_VERSION}." >&2
  60. exit 1
  61. fi
  62. FORMAT_ARGS=(-i)
  63. if [[ "$MODE" == "check" ]]; then
  64. FORMAT_ARGS=(--dry-run --Werror)
  65. fi
  66. find main components -path components/u8g2 -prune -o \( -name "*.c" -o -name "*.h" \) -print0 \
  67. | xargs -0 "$CLANG_FORMAT_BIN" "${FORMAT_ARGS[@]}"
  68. if [[ "$MODE" == "check" ]]; then
  69. echo "All source files are clang-formatted"
  70. else
  71. echo "Formatted all source files"
  72. fi