#!/usr/bin/env bash

# Copy me to .git/hooks/pre-commit

set -euo pipefail

if [[ "${GIT_REFLOG_ACTION:-}" == 'rebase (reword)' ]];then
  exit 0
fi

tmpdir=
cleanup_tmpdir() {
  if [[ "$tmpdir" && -e "$tmpdir" ]];then
    rm -rf "$tmpdir"
  fi
}
trap cleanup_tmpdir EXIT

# Check out the git index (what's about to be committed) in a temporary
# directory & run the supplied command there.
in_git_index_in_tmpdir() {
  tmpdir=$(mktemp -d)
  [[ "$tmpdir" && -d "$tmpdir" ]]
  start_index=$(sha256sum "${GIT_INDEX_FILE:-.git/index}")
  git checkout-index --prefix="$tmpdir/" -a
  pushd "$tmpdir"
  "$@"
  popd
  end_index=$(sha256sum "${GIT_INDEX_FILE:-.git/index}")
  if [[ "$start_index" != "$end_index" ]];then
    echo "Index changed while pre-commit tests were running.  Aborting!"
    exit 1
  fi
}

verify() {
  cargo test --frozen
  cargo clippy --frozen -- -D warnings \
    -W clippy::pedantic \
    -W clippy::clone_on_ref_ptr \
    -W clippy::if_then_some_else_none \
    -W clippy::impl_trait_in_params \
    -W clippy::pattern_type_mismatch \
    -W clippy::shadow_reuse \
    -W clippy::shadow_unrelated \
    -W clippy::str_to_string \
    -W clippy::try_err \
    -A clippy::missing_errors_doc
  find . -name target -prune -o -name '*.rs' -exec rustfmt --check -- {} +
}

in_git_index_in_tmpdir verify
