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} |
@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
@holtkamp Thanks for the pointer, I fixed the
expr
statement. Works on OSX and Alpine now.