2

I have installed PHPCS from composer.json

"require-dev": {
    "phpstan/phpstan": "^0.12.93",
    "squizlabs/php_codesniffer": "^3.6"
},

I am using laravel 8 so I have added below code for pre-commit file in .git/hooks/pre-commit file:

#!/bin/sh

# get bash colors and styles here: 
# http://misc.flogisoft.com/bash/tip_colors_and_formatting
C_RESET='\e[0m'
C_RED='\e[31m'
C_GREEN='\e[32m'
C_YELLOW='\e[33m'

function __run() #(step, name, cmd)
{
    local color output exitcode

    printf "${C_YELLOW}[%s]${C_RESET} %-20s" "$1" "$2"
    output=$(eval "$3" 2>&1)
    exitcode=$?

    if [[ 0 == $exitcode || 130 == $exitcode ]]; then
        echo -e "${C_GREEN}OK!${C_RESET}"
    else
        echo -e "${C_RED}NOK!${C_RESET}\n\n$output"
        exit 1
    fi
}

modified="git diff --diff-filter=M --name-only --cached  | grep \".php$\""
ignore="resources/lang,resources/views,bootstrap/helpers,database/migrations,bin"
phpcs="./vendor/bin/phpcs ./app --report=code --colors --report-width=80 --standard=PSR2 --ignore=${ignore}"

__run "1/3" "php lint" "${modified} | xargs -r php -l"
__run "2/3" "code sniffer" "${modified} | xargs -r ${phpcs}"
__run "3/3" "phpstan" "${modified} | xargs -r vendor/bin/phpstan analyse"

But this is giving me below error:

[2/3] code sniffer        NOK!

xargs: ./vendor/bin/phpcs: No such file or directory

EDIT:

Need to add below code


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 "Checking PHP Lint..."
echo $FILES;exit 1;
for FILE in $SFILES
do
    php -l -d display_errors=0 $PROJECT/$FILE
    if [ $? != 0 ]
    then
        echo "Fix the error before commit."
        exit 1
    fi
    FILES="$FILES $PROJECT/$FILE"
done

if [ "$FILES" != "" ]
then
Bhumi Shah
  • 9,323
  • 7
  • 63
  • 104

3 Answers3

2

Worked code so that it would be useful to others:

#!C:/Program\ Files/Git/usr/bin/sh.exe

PROJECT=`php -r "echo dirname(dirname(realpath('$0')));"`

STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".php\{0,1\}$")

if [[ "$STAGED_FILES" = "" ]]; then
  exit 0
fi

PASS=true

echo " Validating PHPCS:"

#doesnt matter where git was ran...just get absolute path to the .git folder
gitBase=`git rev-parse --absolute-git-dir`


# Check for phpcs
which ${gitBase}/../<path>/vendor/bin/phpcs &> /dev/null
if [[ "$?" == 1 ]]; then
  echo " Please install PHPCS "
  exit 1
fi

RULESET="$PROJECT/.githooks/ruleset.xml"

for FILE in $STAGED_FILES
do
  ${gitBase}/../<path>/vendor/bin/phpcs --colors --standard="$RULESET"  -n -p "$FILE"

  if [[ "$?" == 0 ]]; then
    echo "PHPCS Passed: $FILE "
  else
    echo "PHPCS Failed: $FILE "
    PASS=false
  fi
done

echo " PHPCS validation completed! "

if ! $PASS; then
  echo " COMMIT FAILED:  Your commit contains files that should pass PHPCS but do not. Please fix the PHPCS errors and try again. "
  exit 1
else
  echo " COMMIT SUCCEEDED "
fi

exit $?

and ruleset.xml is

<?xml version="1.0"?>
<ruleset name="PHP_CodeSniffer">
    <description>The coding standard for our project.</description>
    <rule ref="PSR2" />

    <file>app</file>
    <file>bootstrap</file>
    <file>config</file>
    <file>database</file>
    <file>resources</file>
    <file>routes</file>
    <file>tests</file>

    <exclude-pattern>bootstrap/cache/*</exclude-pattern>
    <exclude-pattern>bootstrap/autoload.php</exclude-pattern>
    <exclude-pattern>*/migrations/*</exclude-pattern>
    <exclude-pattern>*/seeds/*</exclude-pattern>
    <exclude-pattern>*.blade.php</exclude-pattern>
    <exclude-pattern>*.js</exclude-pattern>
    <exclude-pattern>tests/*</exclude-pattern>
    <!-- Show progression -->
    <arg value="p"/>
</ruleset>
Bhumi Shah
  • 9,323
  • 7
  • 63
  • 104
0

This hook comes from "How to setup Git commit hooks for PHP " from Benjamin Delespierre.

You have a similar example in fdemiramon gist, with the comment:

Assumed that you have both phpcs and phpcbf in bin/ folder.
Best practice is to use the dedicated package for phpcs: squizlabs/PHP_CodeSniffer

That means: include a dependency for squizlabs/php_codesniffer in your composer.json file (which you did).
For example:

{
    "require-dev": {
        "squizlabs/php_codesniffer": "3.*"
    }
}

You will then be able to run PHP_CodeSniffer from the vendor bin directory:

./vendor/bin/phpcs -h
./vendor/bin/phpcbf -h

If using the full path (/d/Xampp/htdocs/project/vendor/bin/phpcs) does not work, even tough, in a git bash shell, ls /d/Xampp/htdocs/project/vendor/bin/phpcs does work, do check, as commented, the end of lines used for that file.
You can get the root folder with, as I mentioned here, git rev-parse --git-dir.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

I hope you just forget to run composer install after adding require-dev to composer.

but I have made the hook you have posted in my ./.git/hooks/pre-commit and try to commit .php files. and I had got no error.

either i have pwd in the hook script function and it print the project root directory. and everything seems fine. since.

from your comment i just think you are running on windows:

you have to write this:

#!C:/Program\ Files/Git/usr/bin/sh.exe

instead of unix shebang:

#!/bin/sh

Desired Path

The desired git repository initialized & composer initialize is your project base directory

suppose this is your base directory: /d/Xampp/htdocs/proj/, then your composer generated should be under this directory:

/d/Xampp/htdocs/proj/composer.json
/d/Xampp/htdocs/proj/composer.lock
/d/Xampp/htdocs/proj/vendor/

Also, your .git directoy should be in this directory:

/d/Xampp/htdocs/proj/.git/

from the posted result from pwd, I think your git directory is under the:

/d/Xampp/htdocs/proj/api/v2/.git/

so i suggest to delete the /d/Xampp/htdocs/proj/api/v2/.git/ directory, then go to the cd D:\\Xampp\htdocs\proj, and git init, it should create a new .git directory under D:\\Xampp\htdocs\proj.

Change Directory from the script

the pwd prints the current directory, It seems when hook script start to run its path is what pwd has been reported.

you can add this lien before the line output=...

cd ../..
pwd

if the printed tab is somewhere else instead of your project base directory, you can change directory with the cd .

Abilogos
  • 4,777
  • 2
  • 19
  • 39