pre-commit 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. set +e
  4. git diff-files --quiet
  5. is_unclean=$?
  6. set -e
  7. # Revert `git stash` on exit
  8. function revert_git_stash {
  9. >&2 echo "Unstashing uncommitted changes..."
  10. git stash pop -q
  11. }
  12. # Stash pending changes and revert them when script ends
  13. if [ -z "${NO_STASH:-}" ] && [ $is_unclean -ne 0 ]; then
  14. >&2 echo "Stashing uncommitted changes..."
  15. GIT_LITERAL_PATHSPECS=0 git stash -q --keep-index
  16. trap revert_git_stash EXIT
  17. fi
  18. export FLAKEBOX_GIT_LS
  19. FLAKEBOX_GIT_LS="$(git ls-files)"
  20. export FLAKEBOX_GIT_LS_TEXT
  21. FLAKEBOX_GIT_LS_TEXT="$(echo "$FLAKEBOX_GIT_LS" | grep -v -E "\.(png|ods|jpg|jpeg|woff2|keystore|wasm|ttf|jar|ico|gif)\$")"
  22. function check_nothing() {
  23. true
  24. }
  25. export -f check_nothing
  26. function check_cargo_fmt() {
  27. set -euo pipefail
  28. flakebox-in-each-cargo-workspace cargo fmt --all --check
  29. }
  30. export -f check_cargo_fmt
  31. function check_cargo_lock() {
  32. set -euo pipefail
  33. # https://users.rust-lang.org/t/check-if-the-cargo-lock-is-up-to-date-without-building-anything/91048/5
  34. flakebox-in-each-cargo-workspace cargo update --workspace --locked |& while read -r note ; do echo "$note (cargo)"; done
  35. }
  36. export -f check_cargo_lock
  37. function check_leftover_dbg() {
  38. set -euo pipefail
  39. errors=""
  40. for path in $(echo "$FLAKEBOX_GIT_LS_TEXT" | grep '.*\.rs'); do
  41. if grep 'dbg!(' "$path" > /dev/null; then
  42. >&2 echo "$path contains dbg! macro"
  43. errors="true"
  44. fi
  45. done
  46. if [ -n "$errors" ]; then
  47. >&2 echo "Fix the problems above or use --no-verify" 1>&2
  48. return 1
  49. fi
  50. }
  51. export -f check_leftover_dbg
  52. function check_semgrep() {
  53. set -euo pipefail
  54. # semgrep is not available on MacOS
  55. if ! command -v semgrep > /dev/null ; then
  56. >&2 echo "Skipping semgrep check: not available"
  57. return 0
  58. fi
  59. if [ ! -f .config/semgrep.yaml ] ; then
  60. >&2 echo "Skipping semgrep check: .config/semgrep.yaml doesn't exist"
  61. return 0
  62. fi
  63. if [ ! -s .config/semgrep.yaml ] ; then
  64. >&2 echo "Skipping semgrep check: .config/semgrep.yaml empty"
  65. return 0
  66. fi
  67. env SEMGREP_ENABLE_VERSION_CHECK=0 \
  68. semgrep -q --error --no-rewrite-rule-ids --config .config/semgrep.yaml
  69. }
  70. export -f check_semgrep
  71. function check_shellcheck() {
  72. set -euo pipefail
  73. for path in $(echo "$FLAKEBOX_GIT_LS_TEXT" | grep -E '.*\.sh$'); do
  74. shellcheck --severity=warning "$path"
  75. done
  76. }
  77. export -f check_shellcheck
  78. function check_trailing_newline() {
  79. set -euo pipefail
  80. errors=""
  81. for path in $(echo "$FLAKEBOX_GIT_LS_TEXT"); do
  82. # extra branches for clarity
  83. if [ ! -s "$path" ]; then
  84. # echo "$path is empty"
  85. true
  86. elif [ -z "$(tail -c 1 < "$path")" ]; then
  87. # echo "$path ends with a newline or with a null byte"
  88. true
  89. else
  90. >&2 echo "$path doesn't end with a newline" 1>&2
  91. errors="true"
  92. fi
  93. done
  94. if [ -n "$errors" ]; then
  95. >&2 echo "Fix the problems above or use --no-verify" 1>&2
  96. return 1
  97. fi
  98. }
  99. export -f check_trailing_newline
  100. function check_trailing_whitespace() {
  101. set -euo pipefail
  102. rev="HEAD"
  103. if ! git rev-parse -q 1>/dev/null HEAD 2>/dev/null ; then
  104. >&2 echo "Warning: no commits yet, checking against --root"
  105. rev="--root"
  106. fi
  107. if ! git diff --check $rev ; then
  108. >&2 echo "Trailing whitespace detected. Please remove them before committing."
  109. return 1
  110. fi
  111. }
  112. export -f check_trailing_whitespace
  113. function check_typos() {
  114. set -euo pipefail
  115. if ! echo "$FLAKEBOX_GIT_LS_TEXT" | typos --file-list - --force-exclude ; then
  116. >&2 echo "Typos found: Valid new words can be added to '.typos.toml'"
  117. return 1
  118. fi
  119. }
  120. export -f check_typos
  121. parallel \
  122. --nonotice \
  123. ::: \
  124. check_cargo_fmt \
  125. check_cargo_lock \
  126. check_leftover_dbg \
  127. check_semgrep \
  128. check_shellcheck \
  129. check_trailing_newline \
  130. check_trailing_whitespace \
  131. check_typos \
  132. check_nothing