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