#!/bin/bash
#
# To enable this hook, rename this file to "pre-commit" and copy into the
# ../.git/hooks directory.


function check_no_diffmarkers_or_whitespace_errors {
  # If there are whitespace errors, print the offending file names and fail.
  set -e
  git diff-index --check --cached "${1}" --
  set +e
}


function reformat {
  # Reformat the files in-place and re-add any that were changed.
  #
  # Note that this has the side effect of incorporating changes to staged files
  # that were not themselves staged. E.g., if you edit a file, `git add`, then
  # edit some more, then commit, all of the changes will be committed, not just
  # the staged ones. Depending on typical workflows it might be better to do
  # something more complicated here, or to just have the hook fail instead of
  # perform an in-place fix.
  local files_to_format="$(echo "${changed_python_filenames}" | grep -v '3rdparty')"
  if [[ -n "${files_to_format}" ]]; then
    hatch fmt
    hatch run types:check

    echo "${files_to_format}" | xargs git add
  fi
}

function check_no_donotsubmit {
  local filenames="$1"

  if [[ -z "${filenames}" ]]; then
    return
  fi

  set +e
  output="$(grep -H -ni 'DONOTSUBMIT' -- "$1" 2>/dev/null)"
  found=$?
  set -e

  if [[ $found -eq 0 ]]; then
    echo "${output}"
    echo "DONOTSUBMIT tag found, aborting"
    exit 1
  fi
}


if git rev-parse --verify HEAD >/dev/null 2>&1; then
  against=HEAD
else
  # Initial commit: diff against an empty tree object
  against=$(git hash-object -t tree /dev/null)
fi

# Redirect output to stderr.
exec 1>&2


added_and_modified_filenames="$(git diff --cached --name-only --diff-filter=d)"
changed_python_filenames="$(echo "${added_and_modified_filenames}" | \
                            grep -E '.*\.py$')"


# Allow blank line at EOF.
git config --local core.whitespace -blank-at-eof

reformat

check_no_donotsubmit "${changed_python_filenames}"
check_no_diffmarkers_or_whitespace_errors "${against}"

