Skip to content

Instantly share code, notes, and snippets.

@GeekaholicLin
Last active May 8, 2018 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeekaholicLin/3a204dc7b47125ffba5afe0b6875a21c to your computer and use it in GitHub Desktop.
Save GeekaholicLin/3a204dc7b47125ffba5afe0b6875a21c to your computer and use it in GitHub Desktop.
pre-receive hooks for eslint and stylelint
#! /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