mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	 0e4ee5935a
			
		
	
	
		0e4ee5935a
		
	
	
	
	
		
			
			Derived from https://github.com/githubbrowser/Pre-commit-hooks and https://gitlab.cern.ch/GeantV/geant/blob/master/hooks/pre-commit-clang-format
		
			
				
	
	
		
			142 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # git pre-commit hook that runs an clang-format stylecheck.
 | |
| # Features:
 | |
| #  - abort commit when commit does not comply with the style guidelines
 | |
| #  - create a patch of the proposed style changes
 | |
| # Modifications for clang-format by rene.milk@wwu.de
 | |
| 
 | |
| # This file is part of a set of unofficial pre-commit hooks available
 | |
| # at github.
 | |
| # Link:    https://github.com/githubbrowser/Pre-commit-hooks
 | |
| # Contact: David Martin, david.martin.mailbox@googlemail.com
 | |
| 
 | |
| # Some quality of life modifications made for Godot Engine.
 | |
| 
 | |
| ##################################################################
 | |
| # SETTINGS
 | |
| # Set path to clang-format binary
 | |
| # CLANG_FORMAT="/usr/bin/clang-format"
 | |
| CLANG_FORMAT=`which clang-format`
 | |
| 
 | |
| # Remove any older patches from previous commits. Set to true or false.
 | |
| # DELETE_OLD_PATCHES=false
 | |
| DELETE_OLD_PATCHES=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 true only files matching one of the extensions are parsed with clang-format.
 | |
| # PARSE_EXTS=true
 | |
| PARSE_EXTS=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"
 | |
| 
 | |
| # 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_extension() {
 | |
|     local filename=$(basename "$1")
 | |
|     local extension=".${filename##*.}"
 | |
|     local ext
 | |
| 
 | |
|     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 "$CLANG_FORMAT" ] ; then
 | |
|     printf "Error: clang-format 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-clang-format"
 | |
| suffix="$(date +%s)"
 | |
| patch="/tmp/$prefix-$suffix.patch"
 | |
| 
 | |
| # clean up any older clang-format 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 file if we do check for file extensions and the file
 | |
|     # does not match any of the extensions specified in $FILE_EXTS
 | |
|     if $PARSE_EXTS && ! matches_extension "$file"; then
 | |
|         continue;
 | |
|     fi
 | |
| 
 | |
|     # clang-format our sourcefile, create a patch with diff and append it to our $patch
 | |
|     # The sed call is necessary to transform the patch from
 | |
|     #    --- $file timestamp
 | |
|     #    +++ - timestamp
 | |
|     # to both lines working on the same file and having a a/ and b/ prefix.
 | |
|     # Else it can not be applied with 'git apply'.
 | |
|     "$CLANG_FORMAT" -style=file "$file" | \
 | |
|         diff -u "$file" - | \
 | |
|         sed -e "1s|--- |--- a/|" -e "2s|+++ -|+++ b/$file|" >> "$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 clang-format 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 clang-format 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
 |