clang-format.bash 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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:
  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
  64. clang-format-3.8
  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. # Select listing mode.
  80. case "$mode" in
  81. '') echo "$usage"; exit 0 ;;
  82. amend) git_ls='git diff-tree --diff-filter=AM --name-only HEAD -r --no-commit-id' ;;
  83. cached) git_ls='git diff-index --diff-filter=AM --name-only HEAD --cached' ;;
  84. modified) git_ls='git diff-index --diff-filter=AM --name-only HEAD' ;;
  85. tracked) git_ls='git ls-files' ;;
  86. *) die "invalid mode: $mode" ;;
  87. esac
  88. # List files as selected above.
  89. $git_ls |
  90. # Select sources with our attribute.
  91. git check-attr --stdin format.clang-format |
  92. grep -e ': format\.clang-format: set$' |
  93. sed -n 's/:[^:]*:[^:]*$//p' |
  94. # Update sources in-place.
  95. tr '\n' '\0' |
  96. xargs -0 "$clang_format" -i