Skip to content

Instantly share code, notes, and snippets.

@jwage
Last active May 3, 2023 06:42
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save jwage/b1614c96ea22ccaf68b7 to your computer and use it in GitHub Desktop.
Save jwage/b1614c96ea22ccaf68b7 to your computer and use it in GitHub Desktop.
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"
@rbaarsma
Copy link

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

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

@bdelespierre
Copy link

bdelespierre commented Aug 11, 2022

Grep pattern is missing heading whitespace:

# instead of 
grep -e '^[AM]\(.*\).php$'

# do
grep -e '^\s*[AM]\(.*\).php$'

@bdelespierre
Copy link

Actually, ls-files does a better job:

git ls-files -m | grep -e '.php$' | xargs vendor/bin/php-cs-fixer fix

@benblub
Copy link

benblub commented May 3, 2023

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