#!/bin/bash##脚本提供功能:Commit提交的Message和代码规范是否符合统一规范
##分三个部分:
# 1.变量定义部分
# 2.校验部分:注释校验&代码分析
# 3.初始化入口
## 校验流程:
# 1.先做提交注释校验,校验的规则:是否已${TYPE_LIST}定义的开头,且内容长度是否大于${COMMIT_MESSAGE_MIN_LENGTH}
# 2.如果是master分之,修改了pom文件还会校验是否存在snapshot版本的jar
# 3.最后代码规范校验
## (单个项目校验)文件放置目录
# 1./var/opt/gitlab/git-data/repositories/@hashed/xx/xx/xx.git或者/var/opt/gitlab/git-data/repositories/${group}/${project_name}.git/
# 2.创建custom_hooks目录
# 3.在custom_hooks目录下创建pre-receive文件,并保持776可执行权限,且保持该文件权限:chown git:git pre-receive 以及阿里云的p3c-pmd的jar包权限
# 4.给chown -R git:git custom_hooks
# 5.官方文档说明:https://docs.gitlab.com/ee/administration/custom_hooks.html#setup####### 初始化变量部分 ########### 定义java_home变量 需要修改你配置的java_home
JAVA_HOME=/usr/local/jdk1.8.0_141
## 是否开启commit message的校验:0是,1否
CHECK_COMMIT_MESSAGE_ON=0
## 是否开启代码检查:0是,1否
CHECK_CODE_RULE_ON=0
## 是否校验master上的pom文件是否包含snapshot:0是,1否
CHECK_MASTER_POM_SNAPSHOT_ON=1
## 注释内容最小长度,默认20
COMMIT_MESSAGE_MIN_LENGTH=20
### 代码校验规则:0使用阿里云P3C规则,1使用checkStyle
CODE_RULE_TYPE=0## 定义提交开头类型字符规则
## e.g: fix:测试提交bug修复,Bug编号#12
TYPE_LIST=('feat:'   #新功能feature'update:' #在feat内修改'fix:'  #修补bug'docs:'  #文档'style:' #格式化,不影响代码运行的变动'refactor:' #重构'pref:'  #性能优化'test:'  #增加测试'chore:'  #构建过程或辅助工具的变动#'[ci skip]'  #忽略校验
)## 获取当前路径
BASE_PATH=$(cd `dirname $0`; pwd)
echo 'BASE_PATH: '$BASE_PATH#定义和组装校验规则
declare -a regex_list
arrLen=${#TYPE_LIST[@]}
for ((i=0;i<$arrLen;i++)) doregex_list[i]='^'${TYPE_LIST[i]}
done
regex_list[$arrLen+1]='^[ci skip]:'
#echo "reg_list=== "${regex_list[@]}
separator="|"
## 合并成一个完整的正则表达式
regex="$( printf "${separator}%s" "${regex_list[@]}" )"
#echo "type regex: "$regex
## 去除头部的 |
regex=${regex:${#separator}}
#echo "regex: "$regex## 定义注释出错提示信息
tips_msg="$( printf "${separator}%s" "${TYPE_LIST[@]}" )"
tips_msg=${tips_msg:${#separator}}
####### 初始化变量部分 ################ 校验部分:注释校验&代码分析###########
## 校验commit message
validate_commit_message()
{oldrev=$(git rev-parse $1)newrev=$(git rev-parse $2)refname="$3"#echo 'Old version: '$oldrev#echo 'New version: '$newrev#echo 'Branch: '$refname## git 命令#GITCMD="git"## 按时间倒序列出 commit  找出两个版本之间差异的版本号集合  oldrev~newrevcommitList=`git rev-list $oldrev..$newrev`#echo 'commitList: '$commitListsplit=($commitList)#echo 'split: '$split# 遍历数组for s in ${split[@]}do#echo “$s”#通过版本号获取仓库中对象实体的类型、大小和内容的信息#比如提交人、作者、邮件、提交时间、提交内容等currentContent=`git cat-file commit $s`#echo 'Commit obj: '$currentContent#获取提交内容msg=`git cat-file commit $s | sed '1,/^$/d'`#echo 'msg: '$msg## merge合并分之直接放行if [[ $msg == *"Merge branch"* ]]; thenecho "Merge branch...skip the checking"else## 做内容校验match=`echo $msg | grep -nE "(${regex})"`#echo 'Match result: '$match## 找到匹配说明是符合规范的if [ "${match}" != "" ]; then## 校验注释长度msg_length=${#msg}#echo "Msg length: ${msg_length}"if [[ ${msg_length} -lt ${COMMIT_MESSAGE_MIN_LENGTH} ]]; thenecho -e "Error: Commit message should be bigger than ${COMMIT_MESSAGE_MIN_LENGTH} and current commit message length: ${msg_length}"exit 1fi### 找到匹配内容做相应处理,如fix ,校验pom文件等#if [[ "${match}" =~ "fix:" ]]; then## 如果是修补bug,规范有点获取到fix中的ID,然后调用禅道对外的API关闭,其他场景类似#fi# 是否开启校验和master分之isMaster=$(echo $refname | grep "master$")if [ $CHECK_MASTER_POM_SNAPSHOT_ON == 0 ] && [ -n "$isMaster" ]; then# 如果是master分之,并且pom文件发生了变更,判断pom文件是否含有sonapshot的引用pomfile=`git diff --name-only ${oldrev} ${newrev} | grep -e "pom\.xml"`if [[ "${pomfile}" != "" ]]; then#echo $pomfile## 获取pom文件更新的内容pomcontent=`git show $newrev:$pomfile`#echo $pomcontent## 校验pom文件是否包含snapshot版本if [[ $pomcontent =~ 'SNAPSHOT' ]]; thenecho -e "Error: Snapshot version cannot exist in master branch!"exit 1fififi## 其他操作echo "Commit Success!"elseecho -e "Error: Commit comments message should be started with [${tips_msg}]..."exit 1fifidone
}## 代码校验
validate_code_rules()
{echo 'Start code analysis!'oldrev=$(git rev-parse $1)newrev=$(git rev-parse $2)refname="$3"#echo 'Old version: '$oldrev#echo 'New version: '$newrev#echo 'Branch: '$refnameFILES=`git diff --name-only ${oldrev} ${newrev}  | grep -e "\.java$"`if [ -n "$FILES" ]; thenTEMPDIR=$BASE_PATH/"tmp"for FILE in ${FILES}; domkdir -p "${TEMPDIR}/`dirname ${FILE}`" >/dev/nullgit show $newrev:$FILE > ${TEMPDIR}/${FILE}done;MAIN_JAVA_PATH=$TEMPDIR'/src/main'#echo 'Temp update files path: '$MAIN_JAVA_PATH#FILES_TO_CHECK=`find $MAIN_JAVA_PATH -name '*.java'`#echo 'Check files:'${FILES_TO_CHECK}echo 'Aliyun p3c-pmd check starting.....'#echo 'Current shell Path:' $BASE_PATH#echo 'JAVA_HOME:' $JAVA_HOME#echo 'Root directory for java sources: '$MAIN_JAVA_PATHif [[ $CODE_RULE_TYPE == 0 ]]; then## 需要阿里云P3C的插件包p3c-pmd-2.0.0.jar与该脚本在同级目录下echo 'Code analysis for Aliyun-p3c..'#$JAVA_HOME/bin/java -Dpmd.language=en -cp $BASE_PATH/p3c-pmd-2.0.0.jar net.sourceforge.pmd.PMD -d $MAIN_JAVA_PATH -R rulesets/java/ali-comment.xml,rulesets/java/ali-concurrent.xml,rulesets/java/ali-constant.xml,rulesets/java/ali-exception.xml,rulesets/java/ali-flowcontrol.xml,rulesets/java/ali-naming.xml,rulesets/java/ali-oop.xml,rulesets/java/ali-orm.xml,rulesets/java/ali-other.xml,rulesets/java/ali-set.xml -f text$JAVA_HOME/bin/java -Dpmd.language=en -cp $BASE_PATH/p3c-pmd-2.0.0.jar net.sourceforge.pmd.PMD -d $TEMPDIR -R rulesets/java/ali-comment.xml,rulesets/java/ali-concurrent.xml,rulesets/java/ali-constant.xml,rulesets/java/ali-exception.xml,rulesets/java/ali-flowcontrol.xml,rulesets/java/ali-naming.xml,rulesets/java/ali-oop.xml,rulesets/java/ali-other.xml,rulesets/java/ali-set.xml -f textRESULT=$?#echo $RESULTif [ $RESULT -gt 0 ]; thenexit 1;fielif [[ $CODE_RULE_TYPE == 1 ]]; then## 需要CheckStyle插件包checkstyle-8.16-all与该脚本在同级目录下,并且需要对应的CheckStyle.xml模板文件e.g:Cheetah_Checkstyle_ruleset.xmlecho 'Code analysis for CheckStyle..'CHECK_RESULT=`$JAVA_HOME/bin/java -jar $BASE_PATH/checkstyle-8.16-all.jar -c $BASE_PATH/Cheetah_Checkstyle_ruleset.xml $MAIN_JAVA_PATH`if [[ $CHECK_RESULT =~ "[WARN]" ]]; thenecho $CHECK_RESULT | sed 's/\[WARN\]/\n/g'exit 1fielse## 不支持的检查操作echo "Unsupported code validation rule,Please contact the administrator to check the configuration of [CODE_RULE_TYPE] in pre-receive script!"exit 1fiecho 'End code analysis!'rm -rf $TEMPDIRfi
}
####### 校验部分:注释校验&代码分析################## 执行入口###########
pre_receive()
{#commit message 校验if [[ $CHECK_COMMIT_MESSAGE_ON == 0 ]]; thenvalidate_commit_message $1 $2 $3fi#代码规则检查if [[ $CHECK_CODE_RULE_ON == 0 ]]; thenvalidate_code_rules $1 $2 $3fi
}# update hook触发会带参数执行if逻辑
# hooks脚本触发无参数执行else逻辑
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then# Output to the terminal in command line mode - if someone wanted to# resend an email; they could redirect the output to sendmail# themselvespre_receive $2 $3 $1#echo $1'+'$2'+'$3
elsewhile read oldrev newrev refnamedopre_receive $oldrev $newrev $refname#echo $oldrev' '$newrev' '$refnamedone
fi
####### 执行入口###########
exit 0### 参考文献:
# https://www.jianshu.com/p/73073bab7337
# https://www.jianshu.com/p/b87ca8615c9c
# https://blog.csdn.net/u012465508/article/details/80788557

相关安装文档Github地址

Gitlab Custom_hooks集代码规则注释校验脚本(pre-receive)相关推荐

  1. Visual Studio中使用Macros插件给代码添加注释、时间和以及自动脚本

    title: Visual Studio中使用Macros插件给代码添加注释.时间和以及自动脚本 date: 2020-09-11 sidebarDepth: 2 tags: 代码 Visual st ...

  2. 【Microsoft Azure 的1024种玩法】五十九.基于Azure云平台快速搭建GitLab应用实现代码托管

    [简介] GitLab是由GitLab Inc.开发,一款基于Git的完全整合的软体开发平台,以 Git 作为代码管理工具并实现自托管的 Git 项目仓库,本篇文章主要介绍如何在Azure Virtu ...

  3. yolov5——train.py代码【注释、详解、使用教程】

    yolov5--train.py代码[注释.详解.使用教程] yolov5--train.py代码[注释.详解.使用教程] yolov5--train.py代码[注释.详解.使用教程] 前言 1. p ...

  4. php 3 3公派算法代码,PHP常见算法合集代码实例

    许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣,下面是一些常用的算法和实例,大家可以好好学习下 一.文件夹遍历 function allFile($path = __DIR_ ...

  5. php最常见代码,PHP常见算法合集代码实例

    许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣,下面是一些常用的算法和实例,大家可以好好学习下 一.文件夹遍历<?php function allFile($path ...

  6. python画代码-Python教程_Python画Mandelbrot集 代码

    Python教程_Python画Mandelbrot集 代码 作者:Comet 来源: 课课家 www.kokojia.com点击数:278发布时间:2015-06-19 11:17:19 曼德勃罗集 ...

  7. 我的代码和注释都写的像坨屎,那又怎么样?

    一周前,我的朋友圈被一篇 #百度某新员工发飙:前人代码写得像一坨屎,颠覆了对大厂的认知# 的文章刷屏了,评论区也非常热闹. 但让我惊讶的是,几乎所有的声音里都充满着嘲笑与讥讽,有的剑指百度的价值观,那 ...

  8. python代码块注释快捷键_pycharm默认注释与快捷键功能

    pycharm快捷键使用技巧 Ctrl+d 复制当前行.或者选择的块 Ctrl+n 跳转到类 Ctrl+shift+n 快速查找文件名 Ctrl+shift+f 全局查找,快速查找关键字的文件 Ctr ...

  9. 代码注释掉还能执行_日志消息是可执行代码和注释

    代码注释掉还能执行 尽管在一个人的代码中应添加多少注释之间存在意见分歧,但我认为可以肯定地说,大多数开发人员都同意以下代码段中的注释是多余的: // increment the total total ...

最新文章

  1. linux数组shell数组添加内容,shell数组的定义与应用
  2. golang 随机数 实现
  3. July大神---SVM讲解
  4. python知识点博客园_python零碎知识点一
  5. Android为TV端助力 转载:android自定义view实战(温度控制表)!
  6. jMeter Thread group 对应的 constant timer
  7. C#学习笔记——25个经典问题
  8. 专家呼吁建安全漏洞信息共享机制并强化管控
  9. js 表单设计器_准备迎接Vue3,使用Vue Composition API生成干净可扩展的表单
  10. PDFlib使用实例
  11. 万向区块链与生态圈合作伙伴形成RISC-V国际区块链SIG
  12. Bailian1182 POJ1182 食物链【并查集】
  13. WAS集群系列(3):集群搭建:步骤1:准备文件
  14. 三点坐标求三角形的面积
  15. SEO人员,不要见风是雨
  16. 计算机如何用vb文本加密,VB 实现中文文本的加密方法
  17. Java用户注册手机短信验证码校验功能实现
  18. Android:浏览图片,点击放大至全屏效果
  19. 网络摄像头Rtsp直播方案(一)
  20. weight decay 的矩阵描述

热门文章

  1. b5对战平台服务器位置,csgob5对战平台
  2. IT应届实习能不加班?如何逃离996?
  3. 不盲追大模型与堆算力!沈向洋、曹颖与马毅提出理解 AI 的两个基本原理:简约性与自一致性...
  4. 第十篇:读《这才是心理学-看穿伪科学的批判性思维》
  5. c语言关键词中英翻译机编程,课程设计--C语言关键字中英翻译机
  6. 骨传导耳机优缺点?哪些骨传导耳机值得推荐
  7. java环形buff_环形缓冲区.ringbuff(C#和java)
  8. Opencv3学习笔记(C++Python双语)---视屏读取与保存
  9. linux不启动修改rcs文件,Linux启动脚本rcS
  10. 都说幕布适合写作,但是你知道 Effie 吗?