Search code examples
phpbashgnu-parallelphplint

How to lint all the files recursive while printing out only files that have an error?


I want to lint all the files in the current (recursive) directory while printing out only files that have an error, and assign a variable to 1 to be used after the linting is finished.

#!/bin/bash

lint_failed=0
find . -path ./vendor -prune -o -name '*.php' | parallel -j 4 sh -c 'php -l {} || echo -e "[FAIL] {}" && lint_failed=1';

if [ "$lint_failed" -eq "1" ]; then
    exit 1
fi

Example:

[FAIL] ./app/Model/Example.php

The above code doesn't find any errors, but if I run php -l ./app/Model/Example.php an error is returned.


Solution

  • The parallel command already does what you want: it exits 0 if all jobs exit 0, and it exits non-zero if any one job exits non-zero. parallel's exit options are configurable, see the EXIT STATUS section of man parallel for details.

    In your script, the use of || echo obscures the exit status of the jobs, but you can expose this again doing something like this (tested bash 4.4.7 on ubuntu):

    #!/bin/bash
    
    php_lint_file()
    {
        local php_file="$1"
        php -l "$php_file" &> /dev/null
        if [ "$?" -ne 0 ]
        then
            echo -e "[FAIL] $php_file"
            return 1
        fi
    }
    
    export -f php_lint_file
    
    find . -path ./vendor -prune -o -name '*.php' | parallel -j 4 php_lint_file {}
    
    if [ "$?" -ne 0 ]
    then
        exit 1
    fi