#!/usr/bin/env bash # pre-commit hook for degette project. # # Run formatters first, then checkers. # Formatters which changed a file must set the flag 'formatter_updated'. exit_code=0 formatter_updated=0 checker_dirty=0 printf "Stash all unstaged changes.\n" git stash save --keep-index &> /dev/null STAGED_PYTHON_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".py$") # Formatter: black printf "> black ... " if type black &>/dev/null; then if [ -z "$STAGED_PYTHON_FILES" ]; then printf "OK\n" else BLACK_OUTPUT="/tmp/gc-black-output.log" touch $BLACK_OUTPUT if ! echo "$STAGED_PYTHON_FILES" | xargs -d'\n' black --check &>$BLACK_OUTPUT; then echo "$STAGED_PYTHON_FILES" | xargs -d'\n' black &>$BLACK_OUTPUT tail -1 $BLACK_OUTPUT formatter_updated=1 else printf "OK\n" fi fi else printf "SKIP: program not found\n" printf "HINT: Install black with 'pip3 install black' (black requires Python>=3.6)\n" fi # Formatter: isort printf "> isort ... " if type isort &>/dev/null; then if [ -z "$STAGED_PYTHON_FILES" ]; then printf "OK\n" else ISORT_OUTPUT="/tmp/gc-isort-output.log" touch $ISORT_OUTPUT if ! echo "$STAGED_PYTHON_FILES" | xargs -d'\n' isort --check-only &>$ISORT_OUTPUT; then echo "$STAGED_PYTHON_FILES" | xargs -d'\n' isort &>$ISORT_OUTPUT printf "Reformatted.\n" formatter_updated=1 else printf "OK\n" fi fi else printf "SKIP: program not found\n" printf "HINT: Install isort with 'pip install isort'\n" fi # Checker: flake8 printf "> flake8 ... " if type flake8 &>/dev/null; then if [ -z "$STAGED_PYTHON_FILES" ]; then printf "OK\n" else FLAKE8_OUTPUT="/tmp/gc-flake8-output.log" touch $FLAKE8_OUTPUT # fix black incompatibility, sometimes flake8 is not PEP8-compliant if ! echo "$STAGED_PYTHON_FILES" | xargs -d'\n' flake8 --ignore=E203,W503 &>$FLAKE8_OUTPUT; then printf "FAIL\n" cat $FLAKE8_OUTPUT checker_dirty=1 else printf "OK\n" fi fi else printf "SKIP: program not found\n" printf "HINT: Install flake8 with 'pip install flake8'\n" fi # End if [ $checker_dirty -ne 0 ] then printf ">>> Checker(s) detect(s) issue(s)\n" printf " You can still commit and push :)\n" printf " Be warned that our CI may cause you more trouble.\n" fi # In some cases, black makes some changes that are reverted by isort: # the second condition checks whether some changes have been made at the end of the day. # Indeed, when this case applies, one cannot commit using this hook. if [ $formatter_updated -ne 0 ] then printf ">>> Working tree updated by formatter(s)\n" printf " Add changes to staging area and retry.\n" exit_code=1 fi printf "\n" printf "Unstash all unstaged changes.\n" git stash pop &> /dev/null exit $exit_code