Skip to content

Instantly share code, notes, and snippets.

@nmicht
Last active January 29, 2021 12:58
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nmicht/b7e8878ba84ff36784f623f82b09d9fa to your computer and use it in GitHub Desktop.
Save nmicht/b7e8878ba84ff36784f623f82b09d9fa to your computer and use it in GitHub Desktop.
Force PHP standards with Git hooks and Code Sniffer

Force PHP standards with Git hooks and Code Sniffer

Phpcs Dependency

First, we need a development dependency specified to install phpcs. It looks something like this:

{
    "require-dev": [
        "squizlabs/php_codesniffer": "2.0.*@dev"
    ]
}

Install Scripts

Composer has a handy schema entry called scripts. It supports a script hook post-install-cmd. We will use this to install a git pre-commit hook. Adding to our example above:

{
    "require-dev": [
        "squizlabs/php_codesniffer": "2.0.*@dev"
    ],
    "scripts": {
        "post-install-cmd": [
            "bash contrib/setup_hooks.sh"
        ]
    }
}

This will run a bash script called setup.sh when the command composer install is run.

Setup the Git Pre-commit Hook

In our contrib/setup_hooks.sh, we will need to copy a pre-commit script into the .git/hooks directory

This will copy our pre-commit script from the contrib directory to the hooks section of the special git directory and make it executable.

Create the Pre-commit Hook

Whenever a contributing developer attempts to commit their code, it will run our pre-commit script. Now all we need to do is run the code sniffer rules on relavent files specific to this commit. contrib/pre-commit

Based on this tutorial http://tech.zumba.com/2014/04/14/control-code-quality/ with some changes.

#!/bin/bash
PROJECT=`php -r "echo dirname(dirname(dirname(realpath('$0'))));"`
STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
# Determine if a file list is passed
if [ "$#" -eq 1 ]
then
oIFS=$IFS
IFS='
'
SFILES="$1"
IFS=$oIFS
fi
SFILES=${SFILES:-$STAGED_FILES_CMD}
echo -e "\033[0;32m"Checking PHP Lint..."\033[0m"
for FILE in $SFILES
do
php -l -d display_errors=0 $PROJECT/$FILE
if [ $? != 0 ]
then
echo -e "\033[41m"Fix the error before commit."\033[0m"
exit 1
fi
FILES="$FILES $PROJECT/$FILE"
done
if [ "$FILES" != "" ]
then
echo -e "\033[0;32m"Stash your not staged code..."\033[0m"
git stash -u --keep-index
echo -e "\033[0;32m"Running Code Sniffer..."\033[0m"
./vendor/bin/phpcs --standard=PSR2 --encoding=utf-8 -n -p $FILES
if [ $? != 0 ]
then
echo -e "\033[41m"Fix the error before commit."\033[0m"
exit 1
fi
echo -e "\033[0;32m"Recovering your stashed code..."\033[0m"
git stash pop --quiet --index
fi
exit $?
#!/bin/bash
cp contrib/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
Copy link

ghost commented May 20, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment