Skip to content

Instantly share code, notes, and snippets.

@jwage
Last active May 10, 2022
Embed
What would you like to do?
php-cs-fixer git pre commit hook
<?php
return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
->fixers([
'short_array_syntax',
'ordered_use',
])
;
#!/usr/bin/env bash
ROOT="/path/to/your/code"
echo "php-cs-fixer pre commit hook start"
PHP_CS_FIXER="vendor/bin/php-cs-fixer"
HAS_PHP_CS_FIXER=false
if [ -x vendor/bin/php-cs-fixer ]; then
HAS_PHP_CS_FIXER=true
fi
if $HAS_PHP_CS_FIXER; then
git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do
$PHP_CS_FIXER fix --config-file=$ROOT/.php_cs --verbose "$line";
git add "$line";
done
else
echo ""
echo "Please install php-cs-fixer, e.g.:"
echo ""
echo " composer require --dev fabpot/php-cs-fixer:dev-master"
echo ""
fi
echo "php-cs-fixer pre commit hook finish"
@hxgdzyuyi
Copy link

hxgdzyuyi commented Jun 23, 2017

With the --config option you can specify the path to the .php_cs file. in new version.

@rbaarsma
Copy link

rbaarsma commented Sep 21, 2019

I found the running of the php-cs-fixer per line unnecessary slow, changed it to this:

FILES=` git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | tr '\n' ' '`
$PHP_CS_FIXER fix --config=.php_cs ${FILES}
git add ${FILES}

This simplifies the git lines into one single line, because php-cs-fixer can accept multiple paths. It's faster.

@softrebel
Copy link

softrebel commented Feb 3, 2020

if no php file exists in commit, php-cs-fixer run all over the php files of the repo. To avoid this, check FILES to not null then run php-cs-fixer.

FILES=` git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | tr '\n' ' '`
	if [ -z "$FILES" ]
	then
		  echo "php files not found."
	else
		  $PHP_CS_FIXER fix --config=.php_cs --verbose ${FILES}
		  git add ${FILES}
	fi

for more information visit here

@phpfui
Copy link

phpfui commented Mar 26, 2021

I put all the comments together into one script. You can also just include the directories you want enclosed in () and separated by | One problem might be too many files in a commit to specify on a command line, but I did not see any file input options for phpcsfixer.

#!/usr/bin/env bash

echo "php-cs-fixer pre commit hook start"

PHP_CS_FIXER="vendor/bin/php-cs-fixer"
HAS_PHP_CS_FIXER=false

if [ -x $PHP_CS_FIXER ]; then
    HAS_PHP_CS_FIXER=true
fi

if $HAS_PHP_CS_FIXER; then
    FILES=` git status --porcelain | grep -E '^[AM] +(App|public|Tests|views).*\.php$' | cut -c 4- | tr '\n' ' '`
    if [ -z "$FILES" ]
	then
		  echo "No php files found in commit."
	else
		  echo ${FILES}
		  $PHP_CS_FIXER fix --config=.php_cs.dist --verbose ${FILES}
		  git add ${FILES}
	fi
else
    echo ""
    echo "Please install php-cs-fixer, e.g.:"
    echo ""
    echo "  composer require --dev fabpot/php-cs-fixer:dev-master"
    echo ""
    exit 1
fi

echo "php-cs-fixer pre commit hook finish"

@morgan-atproperties
Copy link

morgan-atproperties commented May 6, 2022

This script has worked well for us. However, I did run into one odd behavior. This script will lint and commit all the PHP files that have changed, even if those files are not staged for commit. This tweak lints only staged files:

FILES=`git status --porcelain=v2 | grep -E '^\d [AM].*(App|public|Tests|views).*\.php$' | cut -d ' ' -f 9 | tr '\n' ' '`

@morgan-atproperties
Copy link

morgan-atproperties commented May 6, 2022

We also found that merge commits could end up linting tons of files. We elected to skip merge commits:

if git rev-parse -q --verify MERGE_HEAD; then
    echo "This is a merge commit. Skipping linting just in case it's a big one!"
    exit 0
fi

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