Last active
December 17, 2020 08:29
-
-
Save hollodotme/9c1b805e9a2f946433512563edc4b702 to your computer and use it in GitHub Desktop.
PHP linting shell script - suitable for usage in PHP alpine docker containers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env sh | |
OPTIND=1 | |
EXITCODE=0 | |
# Default parallelization | |
PARALLELIZE=2 | |
# Default file name pattern | |
FILENAME_PATTERN='*.php' | |
echo "PHP linting - looking for syntax errors in PHP files." | |
echo "by Holger Woltersdorf - https://github.com/hollodotme" | |
echo "" | |
helpFunction() { | |
echo "" | |
printf "Usage: %s [-p NUMBER] directory [directory2] [directory(n)] [...]\n\n" "$0" | |
printf "Example: %s -p4 -f'*.phtml' ./src ./tests ./public ./config\n\n" "$0" | |
printf "Every directory will be searched for PHP files.\n" | |
printf "Every PHP file will be checked for syntax errors using \"php -ln\"\n" | |
printf "If syntax errors were found the exit code is != 0\n\n" | |
printf "Options:\n" | |
printf " -f REGEX\tGlob pattern that matches the desired filenames (default: '${FILENAME_PATTERN}')\n" | |
printf " -h\t\tShow this help\n" | |
printf " -p NUMBER\tNumber of parallel processed checks (default: ${PARALLELIZE}, Number of CPUs recommended)\n" | |
echo "" | |
exit 1 | |
} | |
if [ $# -eq 0 ]; then | |
helpFunction | |
fi | |
setParallelization() { | |
local value=${1} | |
local re='[0-9]+$' | |
if [[ $(expr "${value}" : "${re}") != 0 ]]; then | |
printf "ERROR: The value for parallelisation must be a NUMBER.\n\n" >&2 | |
helpFunction | |
fi | |
PARALLELIZE=${value} | |
} | |
setFileNamePattern() { | |
local value=${1} | |
if [[ -z ${value// /} ]]; then | |
printf "ERROR: The value for the filename pattern is empty.\n\n" >&2 | |
helpFunction | |
fi | |
FILENAME_PATTERN=${value} | |
} | |
checkIfDirExists() { | |
local dir=$1 | |
if [ ! -d "${dir}" ]; then | |
printf "ERROR: Directory ${dir} does not exist.\n\n" | |
helpFunction | |
fi | |
} | |
runSyntaxCheckInDir() { | |
local dir="${1}" | |
local pattern="${2}" | |
local parallel="${3}" | |
checkIfDirExists ${dir} | |
printf "Checking %s ..." "${dir}" | |
find "${dir}" -type f -iname "${pattern}" -print0 \ | |
| xargs -0 -n1 -P"${parallel}" php -derror_reporting=-1 -ln \ | |
| (! grep -v "No syntax errors detected") >&2 | |
} | |
while getopts "hp:f:" OPTION; do | |
case ${OPTION} in | |
p) setParallelization "${OPTARG}" ;; | |
f) setFileNamePattern "${OPTARG}" ;; | |
h) helpFunction ;; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
[ "${1:-}" = "--" ] && shift | |
echo "" | |
printf "Filename pattern:\t ${FILENAME_PATTERN}\n" | |
printf "Parallelization:\t ${PARALLELIZE}\n" | |
echo "" | |
for dir in "$@"; do | |
runSyntaxCheckInDir "${dir}" "${FILENAME_PATTERN}" "${PARALLELIZE}" | |
[[ $? -eq 0 ]] && printf "\e[32m ✔ OK\e[0m\n" || EXITCODE=1 | |
done | |
exit ${EXITCODE} |
As suggested @BackEndTea, I added the PHP runtime option -d error_reporting=-1
for maximum error reporting, especially for deprications.
Noice!
On a Mac the parallelisation argument of the "local run" seems not detected properly...
sh phplint.sh -p4 -f'*.php' ./library
PHP linting - looking for syntax errors in PHP files.
by Holger Woltersdorf - https://github.com/hollodotme
expr: syntax error
ERROR: The value for parallelisation must be a NUMBER.
When using the default it workst:
sh phplint.sh -f'*.php' ./library
PHP linting - looking for syntax errors in PHP files.
by Holger Woltersdorf - https://github.com/hollodotme
Filename pattern: *.php
Parallelization: 2
Checking ./library ...
@holtkamp Thanks for the pointer, I fixed the expr
statement. Works on OSX and Alpine now.
--- if [[ $(expr match "${value}" $re) != 0 ]]; then
+++ if [[ $(expr "${value}" : "${re}") != 0 ]]; then
@hollodotme, wow, quick reply. Thanks, both approaches now work from the command line:
sh phplint.sh -p6 -f'*.php' ./src
docker run -it --rm -v $(pwd):/repo -w /repo php:8.0-rc-cli-alpine sh phplint.sh -p6 -f'*.php' ./src
Usage in a Makefile
Note that to make the dockerized approach work when using a Makefile like this:
phplint:
sh phplint.sh -p6 -f'*.php' ./src
phplint-docker:
docker run -it --rm -v $(pwd):/repo -w /repo php:8.0-rc-cli-alpine sh phplint.sh -p6 -f'*.php' ./src
We should use replace $(pwd)
with $(shell pwd)
to prevent an error like: "sh: can't open 'phplint.sh': No such file or directory"
😉
phplint-docker:
docker run -it --rm -v $(shell pwd):/repo -w /repo php:8.0-rc-cli-alpine sh phplint.sh -p6 -f'*.php' ./src
@holtkamp Thanks! I changed the commands above to use $(shell pwd)
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Local run
sh phplint.sh -p4 -f'*.php' ./config ./public ./src ./tests
This means:
Check the directories
./config
,./public
,./src
and./tests
for PHP files with the file extension.php
and check each found file for PHP syntax errors with a parallelization of 4.One-off run in a PHP alpine container
Output / Result
If the code does not contain any syntax errors, the output will look like the following and the exit code is 0 (zero):
If syntax errors were found (e.g. in
./src
), it looks like the following and the exit code is 1 (one):