Created
April 1, 2020 14:12
-
-
Save mpragliola/9c99ee1a30baf1b83e3cd1ba74dfb833 to your computer and use it in GitHub Desktop.
Example of GIT hook: pre-commit
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
#!/bin/bash | |
# --------------- | |
# Color shortcuts | |
# --------------- | |
_B=$(tput setaf 0) | |
_R=$(tput setaf 1) | |
_G=$(tput setaf 2) | |
_Y=$(tput setaf 3) | |
_0=$(tput sgr0) | |
# --------- | |
# Functions | |
# --------- | |
check_command() { | |
hash $1 &> /dev/null \ | |
&& echo " ${_G}✓ ${_Y}Env:${_G} $2 found${_0}" \ | |
|| { | |
echo -n " ${_R}✗ ${_Y}Env:${_R} $2 not found${_0}" | |
[ -z "$3" ] && echo "" || echo "${_Y} → $3" | |
exit 1 | |
} | |
} | |
w_ok() { | |
echo " ${_G}✓ ${_Y}Lint: ${_G}$2${_0} → $1" | |
} | |
w_no() { | |
echo " ${_R}✗ [ $2 ]${_0} → $1" | |
} | |
w_real() { | |
realpath --relative-to=. $1 | |
} | |
# Prerequisites | |
check_command git "GIT" | |
check_command php "PHP CLI" | |
check_command jq "jq (JSON parser)" "sudo apt install jq" | |
check_command yq "yq (YAML parser)" "pip install yq" | |
check_command xmllint "xmllint (XML linter)" "sudo apt install libxml2-utils" | |
# Find GIT | |
GIT_ROOT=$(git rev-parse --show-toplevel 2> /dev/null) \ | |
&& echo " ${_G}✓ ${_Y}Git:${_G} GIT Root found ${_0} → $GIT_ROOT" \ | |
|| { | |
echo " ${_R}✗ ${_Y}Git:${_R} No GIT Root found${_0}" | |
exit 1 | |
} | |
# -------------- | |
# Check composer | |
# -------------- | |
COMPOSER_ROOT="$GIT_ROOT" | |
# Check alternate path(s) for composer other than GIT root | |
if [ -f "$GIT_ROOT/src/composer.json" ]; then | |
COMPOSER_ROOT="$COMPOSER_ROOT/src" | |
fi | |
# Validate composer | |
if [ -f "$GIT_ROOT/composer.json" ] || [ "$composerPath" ]; then | |
ERR=$(composer validate --no-check-publish --no-check-all \ | |
-d "$COMPOSER_ROOT" \ | |
2>&1 > /dev/null) | |
if [ "$?" != 0 ]; then | |
echo " ${_R}✗ Composer:${_Y} Composer not validating" | |
exit 1 | |
else | |
echo " ${_G}✓ ${_Y}Composer:${_G} Valid composer.json${_0} → $(w_real "$COMPOSER_ROOT/composer.json")" | |
fi | |
else | |
echo " ${_G}✓ ${_Y}Composer: No composer.json on root" | |
fi | |
# ------- | |
# Linters | |
# ------- | |
# Loop through the staged files | |
git diff --cached --name-status | while read status path | |
do | |
filename="${path##*/}" | |
ext="${path##*.}" | |
# If the file is just deleted, we do not need to lint | |
if [ "$status" = "D" ]; then | |
echo " ${_G}✓ ${_R}Delete:${_0} → ${_R}$path" | |
continue | |
fi | |
# If the extension is .xyz.dist consider filetype as xyz | |
if [ "$ext" = "dist" ]; then | |
TMP="${filename%.*}" | |
ext="${TMP##*.}" | |
fi | |
# We use git show :$path to compare to the staged file, not the current file | |
# (that can be different from staged if edited or if we added by hunks) | |
case "$ext" in \ | |
php) | |
git show :$path | php -l &> /dev/null \ | |
&& w_ok "$path" "PHP" || { w_no "$path" "PHP" ; exit 1 ; } | |
;; | |
json) | |
git show :$path | jq . &> /dev/null \ | |
&& w_ok "$path" "JSON" || { w_no "$path" "JSON" ; exit 1 ; } | |
;; | |
xml) | |
git show :$path | xmllint - &> /dev/null \ | |
&& w_ok "$path" "XML" || { w_no "$path" "XML" ; exit 1 ; } | |
;; | |
oyml|oyaml) | |
git show :$path | yq . &> /dev/null \ | |
&& w_ok "$path" "YAML" || { w_no "$path" "YAML" ; exit 1 ; } | |
;; | |
lock) | |
[[ "$filename" = 'composer.lock' || "$filename" = "symfony.lock" ]] \ | |
&& git show :$path | jq . &> /dev/null \ | |
&& w_ok "$path" "JSON" || { w_no "$path" "JSON" ; exit 1 ; } | |
;; | |
*) | |
# Other added-modified files pass without linting | |
w_ok "$path" "M" | |
;; | |
esac | |
done || exit 1 | |
# ------------- | |
# Perform tests | |
# ------------- | |
# Test if phpunit is present and test | |
[ -f 'vendor/bin/phpunit' ] && \ | |
vendor/bin/phpunit \ | |
--no-coverage \ | |
# --no-logging \ | |
# --no-extensions \ | |
# --stop-on-error \ | |
# --stop-on-failure \ | |
# --columns max \ | |
# || exit 1 | |
# -------- | |
# Warnings | |
# -------- | |
# | |
# You can put here any non-blocking warnings you may deem fit | |
# Check if some Composer dependencies have "dev-*" versions | |
cat "$COMPOSER_ROOT/composer.json" | jq -r '.require | to_entries[] | "\(.key) \(.value)"' | while read key value | |
do | |
[[ $value == dev-* ]] && echo " ${_Y}! Warning: composer pkg ${_0}$key${_Y} points to dev branch ${_0}$value" | |
done | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment