Hooks: Add pre-commit hook for psf/black formatting
(cherry picked from commit 164826a39b
)
This commit is contained in:
parent
7bf9787921
commit
1ec7a73d1c
4 changed files with 146 additions and 16 deletions
|
@ -5,16 +5,22 @@ contributors to make sure they comply with our requirements.
|
||||||
|
|
||||||
## List of hooks
|
## List of hooks
|
||||||
|
|
||||||
- Pre-commit hook for clang-format: Applies clang-format to the staged files
|
- Pre-commit hook for `clang-format`: Applies `clang-format` to the staged
|
||||||
before accepting a commit; blocks the commit and generates a patch if the
|
files before accepting a commit; blocks the commit and generates a patch if
|
||||||
style is not respected.
|
the style is not respected.
|
||||||
Should work on Linux and macOS. You may need to edit the file if your
|
You may need to edit the file if your `clang-format` binary is not in the
|
||||||
clang-format binary is not in the `$PATH`, or if you want to enable colored
|
`PATH`, or if you want to enable colored output with `pygmentize`.
|
||||||
output with pygmentize.
|
- Pre-commit hook for `black`: Applies `black` to the staged Python files
|
||||||
- Pre-commit hook for makerst: Checks the class reference syntax using `makerst.py`.
|
before accepting a commit.
|
||||||
Should work on Linux and macOS.
|
- Pre-commit hook for `makerst`: Checks the class reference syntax using
|
||||||
|
`makerst.py`.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Copy all the files from this folder into your `.git/hooks` folder, and make sure
|
Copy all the files from this folder into your `.git/hooks` folder, and make
|
||||||
the hooks and helper scripts are executable.
|
sure the hooks and helper scripts are executable.
|
||||||
|
|
||||||
|
The hooks rely on bash scripts and tools which should be in the system `PATH`,
|
||||||
|
so they should work out of the box on Linux/macOS, and might work on Windows
|
||||||
|
when using `git-bash.exe` with `clang-format`, Python, `black`, etc. in the
|
||||||
|
`PATH`.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# as this script. Hooks should return 0 if successful and nonzero to cancel the
|
# as this script. Hooks should return 0 if successful and nonzero to cancel the
|
||||||
# commit. They are executed in the order in which they are listed.
|
# commit. They are executed in the order in which they are listed.
|
||||||
#HOOKS="pre-commit-compile pre-commit-uncrustify"
|
#HOOKS="pre-commit-compile pre-commit-uncrustify"
|
||||||
HOOKS="pre-commit-clang-format pre-commit-makerst"
|
HOOKS="pre-commit-clang-format pre-commit-black pre-commit-makerst"
|
||||||
###########################################################
|
###########################################################
|
||||||
# There should be no need to change anything below this line.
|
# There should be no need to change anything below this line.
|
||||||
|
|
||||||
|
|
128
misc/hooks/pre-commit-black
Executable file
128
misc/hooks/pre-commit-black
Executable file
|
@ -0,0 +1,128 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# git pre-commit hook that runs a black stylecheck.
|
||||||
|
# Based on pre-commit-clang-format.
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# SETTINGS
|
||||||
|
# Set path to black binary.
|
||||||
|
BLACK=`which black`
|
||||||
|
BLACK_OPTIONS="-l 120"
|
||||||
|
|
||||||
|
# Remove any older patches from previous commits. Set to true or false.
|
||||||
|
DELETE_OLD_PATCHES=false
|
||||||
|
|
||||||
|
# File types to parse.
|
||||||
|
FILE_NAMES="SConstruct SCsub"
|
||||||
|
FILE_EXTS="py"
|
||||||
|
|
||||||
|
# Use pygmentize instead of cat to parse diff with highlighting.
|
||||||
|
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
|
||||||
|
# READER="pygmentize -l diff"
|
||||||
|
READER=cat
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# There should be no need to change anything below this line.
|
||||||
|
|
||||||
|
. "$(dirname -- "$0")/canonicalize_filename.sh"
|
||||||
|
|
||||||
|
# exit on error
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# check whether the given file matches any of the set extensions
|
||||||
|
matches_name_or_extension() {
|
||||||
|
local filename=$(basename "$1")
|
||||||
|
local extension=".${filename##*.}"
|
||||||
|
|
||||||
|
for name in $FILE_NAMES; do [[ "$name" == "$filename" ]] && return 0; done
|
||||||
|
for ext in $FILE_EXTS; do [[ "$ext" == "$extension" ]] && return 0; done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# necessary check for initial commit
|
||||||
|
if git rev-parse --verify HEAD >/dev/null 2>&1 ; then
|
||||||
|
against=HEAD
|
||||||
|
else
|
||||||
|
# Initial commit: diff against an empty tree object
|
||||||
|
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$BLACK" ] ; then
|
||||||
|
printf "Error: black executable not found.\n"
|
||||||
|
printf "Set the correct path in $(canonicalize_filename "$0").\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create a random filename to store our generated patch
|
||||||
|
prefix="pre-commit-black"
|
||||||
|
suffix="$(date +%s)"
|
||||||
|
patch="/tmp/$prefix-$suffix.patch"
|
||||||
|
|
||||||
|
# clean up any older black patches
|
||||||
|
$DELETE_OLD_PATCHES && rm -f /tmp/$prefix*.patch
|
||||||
|
|
||||||
|
# create one patch containing all changes to the files
|
||||||
|
git diff-index --cached --diff-filter=ACMR --name-only $against -- | while read file;
|
||||||
|
do
|
||||||
|
# ignore thirdparty files
|
||||||
|
if grep -q "thirdparty" <<< $file; then
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ignore file if not one of the names or extensions we handle
|
||||||
|
if ! matches_name_or_extension "$file"; then
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# format our file with black, create a patch with diff and append it to our $patch
|
||||||
|
# The sed call is necessary to transform the patch from
|
||||||
|
# --- $file timestamp
|
||||||
|
# +++ $file timestamp
|
||||||
|
# to both lines working on the same file and having a/ and b/ prefix.
|
||||||
|
# Else it can not be applied with 'git apply'.
|
||||||
|
"$BLACK" "$BLACK_OPTIONS" --diff "$file" | \
|
||||||
|
sed -e "1s|--- |--- a/|" -e "2s|+++ |+++ b/|" >> "$patch"
|
||||||
|
done
|
||||||
|
|
||||||
|
# if no patch has been generated all is ok, clean up the file stub and exit
|
||||||
|
if [ ! -s "$patch" ] ; then
|
||||||
|
printf "Files in this commit comply with the black formatter rules.\n"
|
||||||
|
rm -f "$patch"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# a patch has been created, notify the user and exit
|
||||||
|
printf "\nThe following differences were found between the code to commit "
|
||||||
|
printf "and the black formatter rules:\n\n"
|
||||||
|
$READER "$patch"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
# Allows us to read user input below, assigns stdin to keyboard
|
||||||
|
exec < /dev/tty
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
|
||||||
|
case $yn in
|
||||||
|
[Yy] ) git apply $patch;
|
||||||
|
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[Nn] ) printf "\nYou can apply these changes with:\n git apply $patch\n";
|
||||||
|
printf "(may need to be called from the root directory of your repository)\n";
|
||||||
|
printf "Aborting commit. Apply changes and commit again or skip checking with";
|
||||||
|
printf " --no-verify (not recommended).\n\n";
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[Ss] ) git apply $patch;
|
||||||
|
git diff-index --cached --diff-filter=ACMR --name-only $against -- | while read file;
|
||||||
|
do git add $file;
|
||||||
|
done
|
||||||
|
printf "The patch was applied and the changed files staged. You can now commit.\n\n";
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
* ) echo "Please answer yes or no."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
exit 1 # we don't commit in any case
|
|
@ -15,22 +15,18 @@
|
||||||
|
|
||||||
##################################################################
|
##################################################################
|
||||||
# SETTINGS
|
# SETTINGS
|
||||||
# Set path to clang-format binary
|
# Set path to clang-format binary.
|
||||||
# CLANG_FORMAT="/usr/bin/clang-format"
|
|
||||||
CLANG_FORMAT=`which clang-format`
|
CLANG_FORMAT=`which clang-format`
|
||||||
|
|
||||||
# Remove any older patches from previous commits. Set to true or false.
|
# Remove any older patches from previous commits. Set to true or false.
|
||||||
# DELETE_OLD_PATCHES=false
|
|
||||||
DELETE_OLD_PATCHES=false
|
DELETE_OLD_PATCHES=false
|
||||||
|
|
||||||
# Only parse files with the extensions in FILE_EXTS. Set to true or false.
|
# Only parse files with the extensions in FILE_EXTS. Set to true or false.
|
||||||
# If false every changed file in the commit will be parsed with clang-format.
|
# If false every changed file in the commit will be parsed with clang-format.
|
||||||
# If true only files matching one of the extensions are parsed with clang-format.
|
# If true only files matching one of the extensions are parsed with clang-format.
|
||||||
# PARSE_EXTS=true
|
|
||||||
PARSE_EXTS=true
|
PARSE_EXTS=true
|
||||||
|
|
||||||
# File types to parse. Only effective when PARSE_EXTS is true.
|
# File types to parse. Only effective when PARSE_EXTS is true.
|
||||||
# FILE_EXTS=".c .h .cpp .hpp"
|
|
||||||
FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
|
FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
|
||||||
|
|
||||||
# Use pygmentize instead of cat to parse diff with highlighting.
|
# Use pygmentize instead of cat to parse diff with highlighting.
|
||||||
|
|
Loading…
Reference in a new issue