#!/usr/bin/env bash set -eo pipefail # https://stackoverflow.com/a/72183258/134409 # this hangs in CI (no tty?) # yes 'will cite' | parallel --citation 2>/dev/null 1>/dev/null || true if [ -n "${HOME:-}" ] && [ -d "$HOME" ]; then mkdir -p "$HOME/.parallel" touch "$HOME/.parallel/will-cite" fi # Revert `git stash` on exit function revert_git_stash { >&2 echo "Unstashing uncommitted changes..." git stash pop -q } set +e git diff-files --quiet is_unclean=$? set -e # Stash pending changes and revert them when script ends if [ -z "${NO_STASH:-}" ] && [ $is_unclean -ne 0 ]; then >&2 echo "Stashing uncommitted changes..." GIT_LITERAL_PATHSPECS=0 git stash -q --keep-index trap revert_git_stash EXIT fi export git_ls_files git_ls_files="$(git ls-files)" export git_ls_nonbinary_files git_ls_nonbinary_files="$(echo "$git_ls_files" | xargs file --mime | grep -v "; charset=binary" | cut -d: -f1)" export git_ls_nonbinary_files git_ls_nonbinary_files="$(echo "$git_ls_files" | xargs file --mime | grep -v "; charset=binary" | cut -d: -f1)" function check_nix() { set -eo pipefail # shellcheck disable=SC2046 nixpkgs-fmt --check $(echo "$git_ls_nonbinary_files" | grep -E '.*\.nix$') 2> >(grep -v "0 / 7 would have been reformatted") } export -f check_nix function check_cargo_fmt() { set -eo pipefail # Note: avoid `cargo fmt --all` so we don't need extra stuff in `ci` shell # so that CI is faster # shellcheck disable=SC2046 cargo fmt --all --check } export -f check_cargo_fmt function check_dbg() { set -eo pipefail errors="" for path in $(echo "$git_ls_nonbinary_files" | grep '.*\.rs'); do if grep 'dbg!(' "$path" > /dev/null; then >&2 echo "$path contains dbg! macro" errors="true" fi done if [ -n "$errors" ]; then >&2 echo "Fix the problems above or use --no-verify" 1>&2 return 1 fi } export -f check_dbg function check_semgrep_log() { set -eo pipefail if ! command -v semgrep > /dev/null ; then >&2 echo "Skipping semgrep check" return 0 fi env SEMGREP_ENABLE_VERSION_CHECK=0 \ semgrep -q --error --config .semgrep.log.yaml fedimint-server/ fedimint-core/ } export -f check_semgrep_log function check_semgrep_all() { set -eo pipefail if ! command -v semgrep > /dev/null ; then >&2 echo "Skipping semgrep check" return 0 fi env SEMGREP_ENABLE_VERSION_CHECK=0 \ semgrep -q --error --config .semgrep.all.yaml } export -f check_semgrep_all function check_shellcheck() { set -eo pipefail for path in $(echo "$git_ls_nonbinary_files" | grep -E '.*\.sh$') ; do shellcheck --severity=warning "$path" done } export -f check_shellcheck function check_eof() { set -eo pipefail errors="" for path in $(echo "$git_ls_nonbinary_files" | grep -v -E '.*\.(ods|jpg|png|log)' | grep -v -E '^db/'); do # extra branches for clarity if [ ! -s "$path" ]; then # echo "$path is empty" true elif [ -z "$(tail -c 1 < "$path")" ]; then # echo "$path ends with a newline or with a null byte" true else >&2 echo "$path doesn't end with a newline" 1>&2 errors="true" fi done if [ -n "$errors" ]; then >&2 echo "Fix the problems above or use --no-verify" 1>&2 return 1 fi } export -f check_eof function trailing_space_check(){ set -eo pipefail for path in $(echo "$git_ls_nonbinary_files" | grep -v -E '.*\.(ods|log)' | grep -v -E '^db/'); do if git diff --check --cached; then echo "Trailing whitespace detected. Please remove them before committing." return 1 fi done } export -f trailing_space_check function check_cargo_lock() { set -eo pipefail # https://users.rust-lang.org/t/check-if-the-cargo-lock-is-up-to-date-without-building-anything/91048/5 cargo update --workspace --locked } export -f check_cargo_lock function check_typos() { set -eo pipefail if ! echo "$git_ls_nonbinary_files" | parallel typos {} ; then >&2 echo "Typos found: Valid new words can be added to '_typos.toml'" return 1 fi } export -f check_typos parallel ::: \ check_semgrep_all \ check_semgrep_log \ check_nix \ check_cargo_fmt \ check_dbg \ check_shellcheck \ check_eof \ check_cargo_lock \ check_typos