Skip to content
Snippets Groups Projects

Git hooks - pre-commit for PHP-CS-Fixer

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Joël Sunier

    Description

    This pre-commit hooks run some checks on the staged files to find any errors that are:

    • Whitespace
    • Presence of words like this RegExp : dump\s*\\(|var_dump\s*\\(|print_r\s*\\(|(?<![\\.\w])alert\s*\\(|console\\.\w+\s*\\(

    If there is no initial errors found, then it will check if there is any *.php files in the staged files.

    If yes, it will run friendsofsymfony/php-cs-fixer to automatically fix any errors found by the rules defined in the .php_cs.dist in the root of the project.

    The php-cs-fixer is runned via Docker with this image. There is a special directive (export MSYS_NO_PATHCONV=1) to make the current path ($PWD) compatible with Docker for Windows, otherwise, it would throw an error like this:

    C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Mount denied:
    The source path "D:/Lab/project;C"
    doesn't exist and is not known to Docker.
    See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.
    C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Mount denied:
    The source path "D:/Lab/project;C"
    doesn't exist and is not known to Docker.
    See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

    Requirements

    • Docker >= 17.0
    • bash (can be used with Git bash on Windows)
    • PHP CS configurations in a file named .php_cs.dist at the root of the project

    Installation

    Simply download and move this file to .git/hooks/pre-commit of your working project.

    pre-commit 2.18 KiB
    #!/bin/bash
    
    # display error and exit
    function error_exit
    {
    	LIGHT_RED='\033[1;31m'
    	YELLOW='\033[0;33m'
    	NC='\033[0m' # No Color
    	echo -e "\n${LIGHT_RED}$1${NC}" 1>&2
    	echo -e "Please fix the problem or use ${YELLOW}git commit --no-verify${NC} to ignore" 1>&2
    	exit 1
    }
    
    # Determine against which commit we will execute our diff
    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 there are whitespace errors, print the offending file names and fail.
    # What are considered whitespace errors is controlled by core.whitespace configuration
    # https://git-scm.com/docs/git-diff-index#git-diff-index---check
    if ! git diff-index --check --cached $against --; then
    	error_exit "There are some whitespace errors"
    fi
    
    # get list of files for this commit
    IFS=$'\n'; COMMIT_SCA_FILES=($(git diff-index --cached --name-only --diff-filter=ACMRTUXB $against --)); unset IFS
    
    # Ensure our commit doesn’t contain an illegal command
    FORBIDDEN_WORDS="dump\s*\\(|var_dump\s*\\(|print_r\s*\\(|(?<![\\.\w])alert\s*\\(|console\\.\w+\s*\\("
    
    HAS_PHP=false
    # loop on each file
    for FILE in ${COMMIT_SCA_FILES[@]}; do
    	# ignore generated assets files in web/build
    	if test "${FILE#*web/build}" != "$FILE"; then
    		continue
    	fi
    
    	# Check if the file contains one of the words in LIST
    	if grep --color -Pin $FORBIDDEN_WORDS -- $FILE
    	then
    		error_exit "$FILE contains one or more illegal words."
    	fi
    
    	# check the syntax of php files
    	if [[ $FILE == *.php ]]; then
    		HAS_PHP=true
    		if ! php -l "$FILE" > /dev/null; then
    			error_exit "$FILE contains one or more PHP Parse error."
    		fi
    	fi
    done
    
    #
    # Execute php-cs-fixer
    #
    if $HAS_PHP; then
    	export MSYS_NO_PATHCONV=1
    	PHP_CS_FIXER="docker run --rm --user $(id -u):$(id -g) --volume $(pwd):/project unibeautify/php-cs-fixer"
    
    	BASE_COMMAND_FIX="fix --config=.php_cs.dist --path-mode=intersection"
    
    	$PHP_CS_FIXER $BASE_COMMAND_FIX -q --dry-run -- "${COMMIT_SCA_FILES[@]}"
    	if [ $? -ne 0 ]; then
    		$PHP_CS_FIXER $BASE_COMMAND_FIX -v -- "${COMMIT_SCA_FILES[@]}"
    		error_exit "Some files contained syntax errors!\nThey were fixed, please review the changes and commit again\n"
    	fi
    fi
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment