Skip to content

Commit 3cf269f

Browse files
committed
Also add in hooks for committing
1 parent 95ab68f commit 3cf269f

File tree

5 files changed

+268
-1
lines changed

5 files changed

+268
-1
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ There is a demo project contained within this repository as well that shows how
172172

173173
## Using this module in your own project
174174

175-
176175
Example: Converting a godot-openvr project
177176

178177
1. Remove the `addons/godot-openvr` directory from the project.
@@ -183,6 +182,11 @@ Since the module is laid out like godot-openvr, the basic documentation for inte
183182

184183
The only differences should be: Since there is no OpenXR asset on the store, the godot-openxr directory has to be manually put into the project's addon/ directory and in the project's gdscript the `OpenXR` string has to be used in the `find_interface()` call.
185184

185+
## Hooks
186+
187+
When contributing to the source code for the plugin we highly recommend you installed clang-format and copy the contents of the `hooks` folder into the folder `.git/hooks/`.
188+
This will ensure clang-format is run on any changed files before commiting the changes to github and prevent disappointment when formatting issues prevent changes from being merged.
189+
186190
## License
187191

188192
The source code for the module is released under MIT license (see license file).

hooks/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Git hooks for Godot Engine
2+
3+
This folder contains git hooks meant to be installed locally by Godot Engine
4+
contributors to make sure they comply with our requirements.
5+
6+
## List of hooks
7+
8+
- Pre-commit hook for clang-format: Applies clang-format to the staged files
9+
before accepting a commit; blocks the commit and generates a patch if the
10+
style is not respected.
11+
Should work on Linux and macOS. You may need to edit the file if your
12+
clang-format binary is not in the $PATH, or if you want to enable colored
13+
output with pygmentize.
14+
15+
## Installation
16+
17+
Copy all the files from this folder into your .git/hooks folder, and make sure
18+
the hooks and helper scripts are executable.

hooks/canonicalize_filename.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/sh
2+
3+
# Provide the canonicalize filename (physical filename with out any symlinks)
4+
# like the GNU version readlink with the -f option regardless of the version of
5+
# readlink (GNU or BSD).
6+
7+
# This file is part of a set of unofficial pre-commit hooks available
8+
# at github.
9+
# Link: https://github.com/githubbrowser/Pre-commit-hooks
10+
# Contact: David Martin, [email protected]
11+
12+
###########################################################
13+
# There should be no need to change anything below this line.
14+
15+
# Canonicalize by recursively following every symlink in every component of the
16+
# specified filename. This should reproduce the results of the GNU version of
17+
# readlink with the -f option.
18+
#
19+
# Reference: http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac
20+
canonicalize_filename () {
21+
local target_file="$1"
22+
local physical_directory=""
23+
local result=""
24+
25+
# Need to restore the working directory after work.
26+
local working_dir="`pwd`"
27+
28+
cd -- "$(dirname -- "$target_file")"
29+
target_file="$(basename -- "$target_file")"
30+
31+
# Iterate down a (possible) chain of symlinks
32+
while [ -L "$target_file" ]
33+
do
34+
target_file="$(readlink -- "$target_file")"
35+
cd -- "$(dirname -- "$target_file")"
36+
target_file="$(basename -- "$target_file")"
37+
done
38+
39+
# Compute the canonicalized name by finding the physical path
40+
# for the directory we're in and appending the target file.
41+
physical_directory="`pwd -P`"
42+
result="$physical_directory/$target_file"
43+
44+
# restore the working directory after work.
45+
cd -- "$working_dir"
46+
47+
echo "$result"
48+
}

hooks/pre-commit

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/sh
2+
# Git pre-commit hook that runs multiple hooks specified in $HOOKS.
3+
# Make sure this script is executable. Bypass hooks with git commit --no-verify.
4+
5+
# This file is part of a set of unofficial pre-commit hooks available
6+
# at github.
7+
# Link: https://github.com/githubbrowser/Pre-commit-hooks
8+
# Contact: David Martin, [email protected]
9+
10+
11+
###########################################################
12+
# CONFIGURATION:
13+
# pre-commit hooks to be executed. They should be in the same .git/hooks/ folder
14+
# as this script. Hooks should return 0 if successful and nonzero to cancel the
15+
# commit. They are executed in the order in which they are listed.
16+
#HOOKS="pre-commit-compile pre-commit-uncrustify"
17+
HOOKS="pre-commit-clang-format"
18+
###########################################################
19+
# There should be no need to change anything below this line.
20+
21+
. "$(dirname -- "$0")/canonicalize_filename.sh"
22+
23+
# exit on error
24+
set -e
25+
26+
# Absolute path to this script, e.g. /home/user/bin/foo.sh
27+
SCRIPT="$(canonicalize_filename "$0")"
28+
29+
# Absolute path this script is in, thus /home/user/bin
30+
SCRIPTPATH="$(dirname -- "$SCRIPT")"
31+
32+
33+
for hook in $HOOKS
34+
do
35+
echo "Running hook: $hook"
36+
# run hook if it exists
37+
# if it returns with nonzero exit with 1 and thus abort the commit
38+
if [ -f "$SCRIPTPATH/$hook" ]; then
39+
"$SCRIPTPATH/$hook"
40+
if [ $? != 0 ]; then
41+
exit 1
42+
fi
43+
else
44+
echo "Error: file $hook not found."
45+
echo "Aborting commit. Make sure the hook is in $SCRIPTPATH and executable."
46+
echo "You can disable it by removing it from the list in $SCRIPT."
47+
echo "You can skip all pre-commit hooks with --no-verify (not recommended)."
48+
exit 1
49+
fi
50+
done

hooks/pre-commit-clang-format

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env bash
2+
3+
# git pre-commit hook that runs a clang-format stylecheck.
4+
# Features:
5+
# - abort commit when commit does not comply with the style guidelines
6+
# - create a patch of the proposed style changes
7+
# Modifications for clang-format by [email protected]
8+
9+
# This file is part of a set of unofficial pre-commit hooks available
10+
# at github.
11+
# Link: https://github.com/githubbrowser/Pre-commit-hooks
12+
# Contact: David Martin, [email protected]
13+
14+
# Some quality of life modifications made for Godot Engine.
15+
16+
##################################################################
17+
# SETTINGS
18+
# Set path to clang-format binary
19+
# CLANG_FORMAT="/usr/bin/clang-format"
20+
CLANG_FORMAT=`which clang-format`
21+
22+
# Remove any older patches from previous commits. Set to true or false.
23+
# DELETE_OLD_PATCHES=false
24+
DELETE_OLD_PATCHES=false
25+
26+
# Only parse files with the extensions in FILE_EXTS. Set to true or false.
27+
# If false every changed file in the commit will be parsed with clang-format.
28+
# If true only files matching one of the extensions are parsed with clang-format.
29+
# PARSE_EXTS=true
30+
PARSE_EXTS=true
31+
32+
# File types to parse. Only effective when PARSE_EXTS is true.
33+
# FILE_EXTS=".c .h .cpp .hpp"
34+
FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
35+
36+
# Use pygmentize instead of cat to parse diff with highlighting.
37+
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
38+
# READER="pygmentize -l diff"
39+
READER=cat
40+
41+
##################################################################
42+
# There should be no need to change anything below this line.
43+
44+
. "$(dirname -- "$0")/canonicalize_filename.sh"
45+
46+
# exit on error
47+
set -e
48+
49+
# check whether the given file matches any of the set extensions
50+
matches_extension() {
51+
local filename=$(basename "$1")
52+
local extension=".${filename##*.}"
53+
local ext
54+
55+
for ext in $FILE_EXTS; do [[ "$ext" == "$extension" ]] && return 0; done
56+
57+
return 1
58+
}
59+
60+
# necessary check for initial commit
61+
if git rev-parse --verify HEAD >/dev/null 2>&1 ; then
62+
against=HEAD
63+
else
64+
# Initial commit: diff against an empty tree object
65+
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
66+
fi
67+
68+
if [ ! -x "$CLANG_FORMAT" ] ; then
69+
printf "Error: clang-format executable not found.\n"
70+
printf "Set the correct path in $(canonicalize_filename "$0").\n"
71+
exit 1
72+
fi
73+
74+
# create a random filename to store our generated patch
75+
prefix="pre-commit-clang-format"
76+
suffix="$(date +%s)"
77+
patch="/tmp/$prefix-$suffix.patch"
78+
79+
# clean up any older clang-format patches
80+
$DELETE_OLD_PATCHES && rm -f /tmp/$prefix*.patch
81+
82+
# create one patch containing all changes to the files
83+
git diff-index --cached --diff-filter=ACMR --name-only $against -- | while read file;
84+
do
85+
# ignore thirdparty files
86+
if grep -q "thirdparty" <<< $file; then
87+
continue;
88+
fi
89+
90+
# ignore file if we do check for file extensions and the file
91+
# does not match any of the extensions specified in $FILE_EXTS
92+
if $PARSE_EXTS && ! matches_extension "$file"; then
93+
continue;
94+
fi
95+
96+
# clang-format our sourcefile, create a patch with diff and append it to our $patch
97+
# The sed call is necessary to transform the patch from
98+
# --- $file timestamp
99+
# +++ - timestamp
100+
# to both lines working on the same file and having a/ and b/ prefix.
101+
# Else it can not be applied with 'git apply'.
102+
"$CLANG_FORMAT" -style=file "$file" | \
103+
diff -u "$file" - | \
104+
sed -e "1s|--- |--- a/|" -e "2s|+++ -|+++ b/$file|" >> "$patch"
105+
done
106+
107+
# if no patch has been generated all is ok, clean up the file stub and exit
108+
if [ ! -s "$patch" ] ; then
109+
printf "Files in this commit comply with the clang-format rules.\n"
110+
rm -f "$patch"
111+
exit 0
112+
fi
113+
114+
# a patch has been created, notify the user and exit
115+
printf "\nThe following differences were found between the code to commit "
116+
printf "and the clang-format rules:\n\n"
117+
$READER "$patch"
118+
printf "\n"
119+
120+
# Allows us to read user input below, assigns stdin to keyboard
121+
exec < /dev/tty
122+
123+
while true; do
124+
read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
125+
case $yn in
126+
[Yy] ) git apply $patch;
127+
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
128+
break
129+
;;
130+
[Nn] ) printf "\nYou can apply these changes with:\n git apply $patch\n";
131+
printf "(may need to be called from the root directory of your repository)\n";
132+
printf "Aborting commit. Apply changes and commit again or skip checking with";
133+
printf " --no-verify (not recommended).\n\n";
134+
break
135+
;;
136+
[Ss] ) git apply $patch;
137+
git diff-index --cached --diff-filter=ACMR --name-only $against -- | while read file;
138+
do git add $file;
139+
done
140+
printf "The patch was applied and the changed files staged. You can now commit.\n\n";
141+
break
142+
;;
143+
* ) echo "Please answer yes or no."
144+
;;
145+
esac
146+
done
147+
exit 1 # we don't commit in any case

0 commit comments

Comments
 (0)