code prettify

Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Saturday, 13 February 2016

Using git pre-commit hook for php and js syntax check

This is a followup from my two previous posts on php and js git pre-commit syntax check where I had mentioned how to check for php and js syntax independently using pre-commit with git.



But what if we wanted to check for both php and js syntax at same time while committing. So, I used the scripts used for both and combined them. Below is the final result.

#!/bin/bash

commit_error=false

ROOT_DIR="$(pwd)/"
LIST=$(git diff-index --cached --name-only --diff-filter=ACMR HEAD)
ERRORS_BUFFER=""
for file in $LIST
do
    EXTENSION=$(echo "$file" | grep ".php$")
    if [ "$EXTENSION" != "" ]; then
        ERRORS=$(php -l "$ROOT_DIR$file" 2>&1 | grep "Parse error")
        if [ "$ERRORS" != "" ]; then
            if [ "$ERRORS_BUFFER" != "" ]; then
                ERRORS_BUFFER="$ERRORS_BUFFER\n$ERRORS"
            else
                ERRORS_BUFFER="$ERRORS"
            fi
            echo "Syntax errors found in file: $file "
        fi

        # Check for xdebug statments
        ERRORS=$(grep -nH xdebug_ "$ROOT_DIR$file" | \
                 sed -e 's/^/Found XDebug Statment : /')
        if [ "$ERRORS" != "" ]; then
            if [ "$ERRORS_BUFFER" != "" ]; then
                ERRORS_BUFFER="$ERRORS_BUFFER\n$ERRORS"
            else
                ERRORS_BUFFER="$ERRORS"
            fi
        fi
    fi
done
if [ "$ERRORS_BUFFER" != "" ]; then
    echo
    echo "Found PHP parse errors: "
    echo -e $ERRORS_BUFFER
    echo
    echo "PHP parse errors found. Fix errors and commit again."
    commit_error=true
else
    echo "No PHP parse errors found. Committed successfully."
fi

files=$(git diff --cached --name-only --diff-filter=ACM | grep "\.js$")
if [ "$files" = "" ]; then
    exit 0
fi

pass=true

JS_ERRORS_BUFFER=""

echo -e "\nValidating JavaScript:\n"

for file in ${files}; do
    result=$(jslint ${file} | grep "${file} is OK")

    if [ "$result" != "" ]; then
        echo -e "\t\033[32mJSLint Passed: ${file}\033[0m"
    else
        JS_ERRORS=$(jslint ${file})
        JS_ERRORS_BUFFER="$JS_ERRORS_BUFFER\n$JS_ERRORS"
        echo -e "\t\033[31mJSLint Failed: ${file}\033[0m"
        pass=false
    fi
done

echo -e "\nJavaScript validation complete\n"

if ! $pass; then
    echo -e "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again."
    echo -e $JS_ERRORS_BUFFER
    echo
    commit_error=true
else
    echo -e "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi

if $commit_error; then
    exit 1
fi

Store it in .git/hooks/pre-commit
Give it execute permission: $ chmod +x .git/hooks/pre-commit and it should be good to go :)

Sample output when I try to commit two php files and two js files with syntax errors:

Filenames with code content:

error.php


<?php
$
array = ;

another_error.php

<?php
var_dump(');

error.js

i =

another_error.js

i = k;

$ git commit -m 'Error Commit' error.php another_error.php error.js another_error.js
Output from above error commit:

Syntax errors found in file: another_error.php 
Syntax errors found in file: error.php 

Found PHP parse errors: 
PHP Parse error: syntax error, unexpected ';' in /var/www/html/error.php on line 2
PHP Parse error: syntax error, unexpected '');' (T_ENCAPSED_AND_WHITESPACE) in /var/www/html/another_error.php on line 2

PHP parse errors found. Fix errors and commit again.

Validating JavaScript:

JSLint Failed: error.js
JSLint Failed: another_error.js

JavaScript validation complete

COMMIT FAILED: Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again.

error.js #1 'i' was used before it was defined. i = // Line 1, Pos 1 #2 Unexpected character '(space)'. i = // Line 1, Pos 4 #3 Unexpected '(end)'. i = // Line 1, Pos 3 #4 Stopping. (50% scanned). // Line 1, Pos 3
another_error.js #1 'i' was used before it was defined. i = k; // Line 1, Pos 1 #2 'k' was used before it was defined. i = k; // Line 1, Pos 5

Above script can be further modified to format the output better but is helpful for basic php and js syntax issues and js standard checks in code :)

Friday, 12 February 2016

Associating git hooks with js syntax check

This is a followup article from my previous post.


Here we will be using git pre-commit to check for syntax error while committing in JavaScript files.

We will need nodejs in our system. Please check https://nodejs.org/en/ for downloading and install steps.

Note: I am using ubuntu 14.04 for this setup.

Steps to add pre-commit JavaScript syntax check with git:

1. Use npm to install jslint package globally in your system.

https://www.npmjs.com/package/jslint

$ npm install -g jslint

This should globally install jslint in your system and can be referenced as below to check syntax error for any js file.

$ jslint sample.js

for (i = 0; i < 10; i++)
{
        sum += i;
}

Sample output from above command:
sample.js
 #1 'i' was used before it was defined.
    for (i = 0; i < 10; i++) // Line 1, Pos 6
 #2 'i' was used before it was defined.
    for (i = 0; i < 10; i++) // Line 1, Pos 13
 #3 'i' was used before it was defined.
    for (i = 0; i < 10; i++) // Line 1, Pos 21
 #4 Unexpected '++'.
    for (i = 0; i < 10; i++) // Line 1, Pos 22
 #5 Expected exactly one space between ')' and '{'.
    { // Line 2, Pos 1
 #6 Use spaces, not tabs.
    sum += i; // Line 3, Pos 1
 #7 Expected 'sum' at column 9, not column 2.
    sum += i; // Line 3, Pos 2
 #8 'i' was used before it was defined.
    sum += i; // Line 3, Pos 9
 #9 Expected '}' at column 5, not column 1.
    } // Line 4, Pos 1

Above info is quite informative and helpful to fix basic syntax errors, missing semi-colons, indentation etc.

Correcting the above errors to below code and running jslint again:

var i, sum = 0;

for (i = 0; i < 10; i = i + 1) {
    sum += i;
}

Output from jslint:

sample.js is OK.

Note: Please also refer rules and standards being followed by jslint for checking here. Makes a nice read. :)

2. Now that jslint is globally available, let us use it and create a pre-commit file.
I found below links which highlight the use of it in a script:

http://stackoverflow.com/questions/15703065/setup-pre-commit-hook-jshint
http://dev.venntro.com/2012/11/maintaining-consistent-javascript-with-jslint/

The only disadvantage I see in the script is that it only highlights passed and failed JavaScript files with names and does not specify the error in each.

So, I made a few changes to the script as below (highlighted in blue):

#!/bin/sh

files=$(git diff --cached --name-only --diff-filter=ACM | grep "\.js$")
if [ "$files" = "" ]; then
    exit 0
fi

pass=true

ERRORS_BUFFER=""

echo -e "\nValidating JavaScript:\n"

for file in ${files}; do
    result=$(jslint ${file} | grep "${file} is OK")
    if [ "$result" != "" ]; then
        echo -e "\t\033[32mJSLint Passed: ${file}\033[0m"
    else
        ERRORS=$(jslint ${file})
        ERRORS_BUFFER="$ERRORS_BUFFER\n$ERRORS"
        echo -e "\t\033[31mJSLint Failed: ${file}\033[0m"
        pass=false
    fi
done

echo -e "\nJavaScript validation complete\n"

if ! $pass; then
    echo -e "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again."
    echo -e $ERRORS_BUFFER
    echo 
    exit 1
else
    echo -e "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi

3. Save the above script in your git pre-commit file as below:

$ cd /project/directory/
$ vim .git/hooks/pre-commit

Paste the above content and save it. Then give execute permission to it.

$ chmod +x .git/hooks/pre-commit

And we are done and ready :)

Trying a sample case:

I have two js files named sample.js and another.js with below content:

sample.js:

var i = j;

for (key in names) {
    echo names[key];

}

another.js:

var i = []

Lets try to commit them:

$ git commit -m 'Error Commit' sample.js another.js

Below is the pre-commit check output:

Validating JavaScript:

JSLint Failed: sample.js
JSLint Failed: true.js

JavaScript validation complete

COMMIT FAILED: Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again.

 sample.js #1 'j' was used before it was defined. var i = j; // Line 1, Pos 9 #2 'key' was used before it was defined. for (key in names) { // Line 3, Pos 6 #3 Cannot read property 'kind' of undefined // Line 3, Pos 10

 true.js #1 Expected ';' and instead saw '(end)'. var i = [] // Line 1, Pos 11

The output can be formatted a little bit better to place each line error in a new line of its own. But this simple tool is pretty handy for checking js errors while committing :)

Friday, 5 February 2016

Associating git hooks with php syntax check

Many a times we have faced this problem that when we commit something and it breaks something on the server due to some syntax error.
I know that these can be caught by IDEs and good editors, but sometimes there might be an syntax error introduced after a code merge conflict resolution and commit.

To address this, we can use git pre-commit hooks to check for any syntax errors in the to be committed files.

There is a good script I found which does this at https://github.com/ReekenX/phpcheck-git

Steps to add pre-commit php syntax check with git:

(Issue below commands in your console)

1. $ cd /project/directory/

2. $ cd .git/hooks/

3. Get the pre-commit script file from above github page or from direct link: https://raw.githubusercontent.com/ReekenX/phpcheck-git/master/pre-commit

$ wget https://raw.githubusercontent.com/ReekenX/phpcheck-git/master/pre-commit

4. Give execute permission to it.

$ chmod +x pre-commit

This should be it :)

Now if you try to commit any php file, it will display message about any syntax error. If there are, then it will specify the file, error and line number where the error took place and will abort the commit.

This small tool will help us in better checking our code before being committed :)