1#!/bin/bash 2 3# Git pre-commit hook to check staged Python files for formatting issues with 4# yapf. 5# 6# INSTALLING: Copy this script into `.git/hooks/pre-commit`, and mark it as 7# executable. 8# 9# This requires that yapf is installed and runnable in the environment running 10# the pre-commit hook. 11# 12# When running, this first checks for unstaged changes to staged files, and if 13# there are any, it will exit with an error. Files with unstaged changes will be 14# printed. 15# 16# If all staged files have no unstaged changes, it will run yapf against them, 17# leaving the formatting changes unstaged. Changed files will be printed. 18# 19# BUGS: This does not leave staged changes alone when used with the -a flag to 20# git commit, due to the fact that git stages ALL unstaged files when that flag 21# is used. 22 23# Find all staged Python files, and exit early if there aren't any. 24PYTHON_FILES=(`git diff --name-only --cached --diff-filter=AM | \ 25 grep --color=never '.py$'`) 26if [ ! "$PYTHON_FILES" ]; then 27 exit 0 28fi 29 30########## PIP VERSION ############# 31# Verify that yapf is installed; if not, warn and exit. 32if [ -z $(which yapf) ]; then 33 echo 'yapf not on path; can not format. Please install yapf:' 34 echo ' pip install yapf' 35 exit 2 36fi 37######### END PIP VERSION ########## 38 39########## PIPENV VERSION ########## 40# if [ -z $(pipenv run which yapf) ]; then 41# echo 'yapf not on path; can not format. Please install yapf:' 42# echo ' pipenv install yapf' 43# exit 2 44# fi 45###### END PIPENV VERSION ########## 46 47 48# Check for unstaged changes to files in the index. 49CHANGED_FILES=(`git diff --name-only ${PYTHON_FILES[@]}`) 50if [ "$CHANGED_FILES" ]; then 51 echo 'You have unstaged changes to some files in your commit; skipping ' 52 echo 'auto-format. Please stage, stash, or revert these changes. You may ' 53 echo 'find `git stash -k` helpful here.' 54 echo 55 echo 'Files with unstaged changes:' 56 for file in ${CHANGED_FILES[@]}; do 57 echo " $file" 58 done 59 exit 1 60fi 61 62# Format all staged files, then exit with an error code if any have uncommitted 63# changes. 64echo 'Formatting staged Python files . . .' 65 66########## PIP VERSION ############# 67yapf -i -r ${PYTHON_FILES[@]} 68######### END PIP VERSION ########## 69 70########## PIPENV VERSION ########## 71# pipenv run yapf -i -r ${PYTHON_FILES[@]} 72###### END PIPENV VERSION ########## 73 74 75CHANGED_FILES=(`git diff --name-only ${PYTHON_FILES[@]}`) 76if [ "$CHANGED_FILES" ]; then 77 echo 'Reformatted staged files. Please review and stage the changes.' 78 echo 79 echo 'Files updated:' 80 for file in ${CHANGED_FILES[@]}; do 81 echo " $file" 82 done 83 exit 1 84else 85 exit 0 86fi 87