Last active
May 8, 2018 13:39
-
-
Save GeekaholicLin/3a204dc7b47125ffba5afe0b6875a21c to your computer and use it in GitHub Desktop.
pre-receive hooks for eslint and stylelint
This file contains hidden or 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 | |
date_start=$(date +%s) | |
# colors const | |
red='\033[1;31m' # error | |
green='\033[1;32m' # success | |
yellow='\033[1;33m' # warning | |
cyan='\033[1;36m' # info | |
no_color='\033[0m' # No Color | |
# console func | |
console_info(){ | |
echo -e "${cyan} [INFO] $1 ${no_color}" | |
} | |
console_error(){ | |
echo -e "${red} [ERROR] $1 ${no_color}" | |
} | |
console_success(){ | |
echo -e "${green} [SUCCESS] $1 ${no_color}" | |
} | |
console_warning(){ | |
echo -e "${yellow} [WARNING] $1 ${no_color}" | |
} | |
# business func | |
is_not_linting_branch(){ | |
local branches=("master" "dev" "test" "beta" "staging") | |
local arr='[ "master", "dev", "test", "beta", "staging" ]' | |
echo "${branches[@]:0}" | grep -o $1 > /dev/null 2>&1 | |
if [[ $? -eq 0 ]]; then | |
console_info "branch $1 matches in ${arr}." | |
return 1 | |
else | |
console_info "branch $1 no matches in ${arr}." | |
return 0 | |
fi | |
} | |
no_need_linting(){ | |
git log -1 --pretty=format:%B $1 | grep no_checkstyle > /dev/null | |
if [ $? -eq 0 ]; then | |
console_warning "Commit msg contains \" no_checkstyle \". Accept this push directly." | |
return 0 | |
fi | |
return 1 | |
} | |
copy_file_from_git(){ | |
local source_file=$1 | |
local target_dir=$2 | |
local new_sha1=$3 | |
if [[ -e ${target_dir}/${source_file} ]]; then | |
console_error "File ${source_file} exists in the temp directory." | |
console_error "It may cause by the reason that you push multiply modified branch." | |
console_error "Please split your push into separate operations." | |
rm -rf ${target_dir} | |
exit 1 | |
fi | |
git show ${new_sha1}:${source_file} > ${target_dir}/${source_file} 2> /dev/null | |
if [[ $? -eq 0 ]]; then | |
console_info "Copy \"${source_file}\" to ${target_dir}." | |
else | |
console_error "Can not find needed file named ${source_file}! Reject this push!" | |
rm -rf ${target_dir} | |
exit 1 | |
fi | |
} | |
lint_modified_files(){ | |
console_info "Linting for the $1 files..." | |
npm run "pre-receive:$1" | |
return $? | |
} | |
# variables | |
temp_dir=$(mktemp -d /tmp/code_lint_tmp_XXXXX) | |
oldrev=$1 | |
newrev=$2 | |
refname=$3 | |
null_commit=$(printf '0%.0s' {1..40}) | |
lint_branches=0 | |
js_result_status=1 # may use three variables in the future | |
scss_result_status=1 | |
status=1 | |
while read oldrev newrev refname; do | |
branch=${refname#refs/heads/} | |
console_info "################### Branch [${branch}] ###################" | |
console_info "oldrev: $oldrev." | |
console_info "newrev: $newrev." | |
console_info "refname: $refname." | |
console_info "branch: ${branch}" | |
if is_not_linting_branch ${branch}; then | |
continue; # skip linting when the branch is no matching | |
fi | |
if [[ $newrev = ${null_commit} ]]; then | |
console_warning "Delete the branch named $refname.No need linting." | |
continue; # skip linting when the branch is deleted | |
fi | |
if no_need_linting $newrev; then | |
console_warning "no_need_linting" | |
continue; # skip linting when commit msg contains "no_checkstyle" | |
fi | |
if [[ $oldrev = ${null_commit} ]]; then | |
console_warning "Create a branch named ${branch}." # new branch created | |
oldrev=HEAD | |
fi | |
lint_branches=$[ lint_branches+1 ] | |
console_info "lint_branches: ${lint_branches}" | |
# get the needed files and check if it exists | |
copy_file_from_git ".eslintrc" ${temp_dir} $newrev | |
copy_file_from_git ".stylelintrc" ${temp_dir} $newrev | |
copy_file_from_git "package.json" ${temp_dir} $newrev | |
copy_file_from_git ".npmrc" ${temp_dir} $newrev | |
# get the files that have been modified | |
files=`git diff --name-only ${oldrev}..${newrev}` | |
for file in $files; do | |
# create all the necessary sub directories in the new temp directory | |
mkdir -p "${temp_dir}/`dirname ${file}`" | |
# and output the object content of newrev into it's original file name | |
git show $newrev:$file 1> ${temp_dir}/$file 2> /dev/null | |
done | |
done | |
if [[ ${lint_branches} -eq 0 ]]; then | |
console_info "There is no needed linting branch. Accept this push directly." | |
rm -rf ${temp_dir} | |
exit 0 | |
fi | |
if type node >/dev/null 2>&1; then | |
console_info "Node.js has installed.Skip installing." | |
else | |
console_warning "Cannot found Node.js. Now install nvm and node." | |
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash | |
source ~/.nvm/nvm.sh && nvm install 8.9 && nvm use 8.9 | |
if [[ $? -ne 0 ]]; then | |
console_error "There is something wrong when installing nvm and node." | |
fi | |
fi | |
console_info "Node version: `node -v`" | |
console_info "Installing only devDependencies in package.json file..." | |
cd ${temp_dir} && npm install --only=dev | |
status=$? | |
lint_modified_files js | |
js_result_status=$? | |
lint_modified_files scss | |
scss_result_status=$? | |
# all the status | |
console_info "status: $status" | |
console_info "js_result_status: ${js_result_status}" | |
console_info "scss_result_status: ${scss_result_status}" | |
rm -rf ${temp_dir} | |
date_end=$(date +%s) | |
console_success "Costs $((date_end-date_start)) seconds" | |
exit $[ js_result_status+scss_result_status+status ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment