clang-format.bash 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env bash
  2. #=============================================================================
  3. # Copyright 2015-2017 Kitware, Inc.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #=============================================================================
  17. usage='usage: clang-format.bash [<options>] [--]
  18. --help Print usage plus more detailed help.
  19. --clang-format <tool> Use given clang-format tool.
  20. --amend Filter files changed by HEAD.
  21. --cached Filter files locally staged for commit.
  22. --modified Filter files locally modified from HEAD.
  23. --tracked Filter files tracked by Git.
  24. '
  25. help="$usage"'
  26. Example to format locally modified files:
  27. Utilities/Scripts/clang-format.bash --modified
  28. Example to format locally modified files staged for commit:
  29. Utilities/Scripts/clang-format.bash --cached
  30. Example to format files modified by the most recent commit:
  31. Utilities/Scripts/clang-format.bash --amend
  32. Example to format all files tracked by Git:
  33. Utilities/Scripts/clang-format.bash --tracked
  34. Example to format the current topic:
  35. git filter-branch \
  36. --tree-filter "Utilities/Scripts/clang-format.bash --tracked" \
  37. master..
  38. '
  39. die() {
  40. echo "$@" 1>&2; exit 1
  41. }
  42. #-----------------------------------------------------------------------------
  43. # Parse command-line arguments.
  44. clang_format=''
  45. mode=''
  46. while test "$#" != 0; do
  47. case "$1" in
  48. --amend) mode="amend" ;;
  49. --cached) mode="cached" ;;
  50. --clang-format) shift; clang_format="$1" ;;
  51. --help) echo "$help"; exit 0 ;;
  52. --modified) mode="modified" ;;
  53. --tracked) mode="tracked" ;;
  54. --) shift ; break ;;
  55. -*) die "$usage" ;;
  56. *) break ;;
  57. esac
  58. shift
  59. done
  60. test "$#" = 0 || die "$usage"
  61. # Find a default tool.
  62. tools='
  63. clang-format-18
  64. clang-format
  65. '
  66. if test "x$clang_format" = "x"; then
  67. for tool in $tools; do
  68. if type -p "$tool" >/dev/null; then
  69. clang_format="$tool"
  70. break
  71. fi
  72. done
  73. fi
  74. # Verify that we have a tool.
  75. if ! type -p "$clang_format" >/dev/null; then
  76. echo "Unable to locate a 'clang-format' tool."
  77. exit 1
  78. fi
  79. if ! "$clang_format" --version | grep 'clang-format version 18' >/dev/null 2>/dev/null; then
  80. echo "clang-format version 18 is required (exactly)"
  81. exit 1
  82. fi
  83. # Select listing mode.
  84. case "$mode" in
  85. '') echo "$usage"; exit 0 ;;
  86. amend) git_ls='git diff-tree --diff-filter=AM --name-only HEAD -r --no-commit-id' ;;
  87. cached) git_ls='git diff-index --diff-filter=AM --name-only HEAD --cached' ;;
  88. modified) git_ls='git diff-index --diff-filter=AM --name-only HEAD' ;;
  89. tracked) git_ls='git ls-files' ;;
  90. *) die "invalid mode: $mode" ;;
  91. esac
  92. # List files as selected above.
  93. $git_ls |
  94. # Select sources with our attribute.
  95. git check-attr --stdin format.clang-format |
  96. sed -n '/: format\.clang-format: \(set\|18\)$/ {s/:[^:]*:[^:]*$//p}' |
  97. # Update sources in-place.
  98. xargs -d '\n' "$clang_format" -i