• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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