blob: 3e687394954dc3a9772c3fc52a1d8471782663d9 [file] [log] [blame]
#!/usr/bin/env bash
# Git pre-commit hook to check staged Python files for formatting issues with
# yapf.
#
# INSTALLING: Copy this script into `.git/hooks/pre-commit`, and mark it as
# executable.
#
# This requires that yapf is installed and runnable in the environment running
# the pre-commit hook.
#
# When running, this first checks for unstaged changes to staged files, and if
# there are any, it will exit with an error. Files with unstaged changes will be
# printed.
#
# If all staged files have no unstaged changes, it will run yapf against them,
# leaving the formatting changes unstaged. Changed files will be printed.
#
# BUGS: This does not leave staged changes alone when used with the -a flag to
# git commit, due to the fact that git stages ALL unstaged files when that flag
# is used.
# Find all staged Python files, and exit early if there aren't any.
PYTHON_FILES=()
while IFS=$'\n' read -r line; do PYTHON_FILES+=("$line"); done \
< <(git diff --name-only --cached --diff-filter=AM | grep --color=never '.py$')
if [ ${#PYTHON_FILES[@]} -eq 0 ]; then
exit 0
fi
########## PIP VERSION #############
# Verify that yapf is installed; if not, warn and exit.
if ! command -v yapf >/dev/null; then
echo 'yapf not on path; can not format. Please install yapf:'
echo ' pip install yapf'
exit 2
fi
######### END PIP VERSION ##########
########## PIPENV VERSION ##########
# if ! pipenv run yapf --version 2>/dev/null 2>&1; then
# echo 'yapf not on path; can not format. Please install yapf:'
# echo ' pipenv install yapf'
# exit 2
# fi
###### END PIPENV VERSION ##########
# Check for unstaged changes to files in the index.
CHANGED_FILES=()
while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
< <(git diff --name-only "${PYTHON_FILES[@]}")
if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
echo 'You have unstaged changes to some files in your commit; skipping '
echo 'auto-format. Please stage, stash, or revert these changes. You may '
echo 'find `git stash -k` helpful here.'
echo 'Files with unstaged changes:' "${CHANGED_FILES[@]}"
exit 1
fi
# Format all staged files, then exit with an error code if any have uncommitted
# changes.
echo 'Formatting staged Python files . . .'
########## PIP VERSION #############
yapf -i -r "${PYTHON_FILES[@]}"
######### END PIP VERSION ##########
########## PIPENV VERSION ##########
# pipenv run yapf -i -r "${PYTHON_FILES[@]}"
###### END PIPENV VERSION ##########
CHANGED_FILES=()
while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
< <(git diff --name-only "${PYTHON_FILES[@]}")
if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
echo 'Reformatted staged files. Please review and stage the changes.'
echo 'Files updated: ' "${CHANGED_FILES[@]}"
exit 1
else
exit 0
fi