xref: /aosp_15_r20/external/yapf/plugins/pre-commit.sh (revision 7249d1a64f4850ccf838e62a46276f891f72998e)
1#!/usr/bin/env 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=()
25while IFS=$'\n' read -r line; do PYTHON_FILES+=("$line"); done \
26  < <(git diff --name-only --cached --diff-filter=AM | grep --color=never '.py$')
27if [ ${#PYTHON_FILES[@]} -eq 0 ]; then
28  exit 0
29fi
30
31########## PIP VERSION #############
32# Verify that yapf is installed; if not, warn and exit.
33if ! command -v yapf >/dev/null; then
34  echo 'yapf not on path; can not format. Please install yapf:'
35  echo '    pip install yapf'
36  exit 2
37fi
38######### END PIP VERSION ##########
39
40########## PIPENV VERSION ##########
41# if ! pipenv run yapf --version 2>/dev/null 2>&1; then
42#   echo 'yapf not on path; can not format. Please install yapf:'
43#   echo '    pipenv install yapf'
44#   exit 2
45# fi
46###### END PIPENV VERSION ##########
47
48
49# Check for unstaged changes to files in the index.
50CHANGED_FILES=()
51while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
52  < <(git diff --name-only "${PYTHON_FILES[@]}")
53if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
54  echo 'You have unstaged changes to some files in your commit; skipping '
55  echo 'auto-format. Please stage, stash, or revert these changes. You may '
56  echo 'find `git stash -k` helpful here.'
57  echo 'Files with unstaged changes:' "${CHANGED_FILES[@]}"
58  exit 1
59fi
60
61# Format all staged files, then exit with an error code if any have uncommitted
62# changes.
63echo 'Formatting staged Python files . . .'
64
65########## PIP VERSION #############
66yapf -i -r "${PYTHON_FILES[@]}"
67######### END PIP VERSION ##########
68
69########## PIPENV VERSION ##########
70# pipenv run yapf -i -r "${PYTHON_FILES[@]}"
71###### END PIPENV VERSION ##########
72
73
74CHANGED_FILES=()
75while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
76  < <(git diff --name-only "${PYTHON_FILES[@]}")
77if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
78  echo 'Reformatted staged files. Please review and stage the changes.'
79  echo 'Files updated: ' "${CHANGED_FILES[@]}"
80  exit 1
81else
82  exit 0
83fi
84