# Learning-Summary **Repository Path**: fuyan_u/Learning-Summary ## Basic Information - **Project Name**: Learning-Summary - **Description**: 汇总 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-12-25 - **Last Updated**: 2024-12-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## checkstyle代码校验 #### 1、准备好环境 - jdk与git环境配置 - 了解git hook,们要在git commit之前自动检查style,就需要利用git hook(钩子),查看文档:https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90 ![](assets/60c417b55d974e63b9dea84a623e6d2e&showdoc=.jpg) - checkstyle的jar包(https://github.com/checkstyle/checkstyle/releases ) - style xml配置文件 ```xml ``` - pre-commit脚本 ```bash #!/bin/bash #@author:jimo# #@func:pre-commit# ## cp ./check-style/pre-commit ./.git/hooks/ # 一个打印函数,前后加空行 function print(){ echo "" echo "===========$*============" echo "" } print 避免NPE是程序员的基本修养! print 开始style checking wd=`pwd` print "当前工作目录:$wd" check_jar_path="$wd/check-style/checkstyle-8.20-all.jar" check_xml_path="$wd/check-style/iad-checkstyle.xml" # echo $check_jar_path $check_xml_path # 清空temp文件 rm -f temp is_err=0 for file in `git status --porcelain | sed s/^...// | grep '\.java$'`;do path="$wd/$file" print "检查文件:$path" re=`java -jar $check_jar_path -c $check_xml_path $path >> temp` err=`cat temp | grep "ERROR"` if [[ $err = *"ERROR"* ]];then print $err is_err=1 fi done print "检查完成,祝你好运" rm -f temp if [ $is_err -ne 0 ] then print "请先符合style才能提交!" exit 1 fi exit 0 ``` #### 2、在项目根目录下增加check-style目录来存放文件 #### ![img](assets/1bc22997a3345219b9becd14821b3450&showdoc=.jpg) #### 3、使用 因为.git这个目录是不随项目文件一起提交的,所以不能实现共享,所以需要做一些配置,有两种方案: ##### 第一种方案: 可以拷贝pre-commit到.git/hooks目录下,根目录下执行下面命令: ``` cp ./check-style/pre-commit ./.git/hooks/ ``` ##### 第二种方案: 在根目录下的pom.xml文件增加插件 ```xml com.rudikershaw.gitbuildhook git-build-hook-maven-plugin 3.0.0 ./check-style/ initialize configure ``` 根目录下执行下面命令: ``` mvn compile 或者 mvn install 或者 mvn package ``` ### 二、gitalab远端代码检验,在git push时校验代码 - 一般在仓库的/var/opt/gitlab/git-data/repositories//.git目录下创建目录:custom_hooks,但是因为我们gitlab配置了Use hashed storage,只能在gitlab上查询项目对应的hash值,以MES后端代码为例,仓库地址:/var/opt/gitlab/git-data/repositories/[@hashed](https://github.com/hashed)/45/23/4523540f1504cd17100c4835e85b7eefd49911580f8efff0599a8f283be6b9e3.git ![img](assets/e7d0c8d7670c5365512df4da59e35398&showdoc=.jpg) ![image-20241225154637628](assets/image-20241225154637628.png) 在custom_hooks目录下新增可执行文件:pre-receive (脚本可以是任何ruby、python、shell可执行脚本,没有后缀名,新建后记得授权:chmod +x pre-receive)输入内容如下: ```bash #!/usr/bin/python #coding=utf-8 import os import sys import subprocess import tempfile import shutil __author__ = "zhangqa" class Trigger(object): def __init__(self): ''' 初始化文件列表信息,提交者信息,提交时间,当前操作的分支 ''' self.pushAuthor = "" self.pushTime = "" self.fileList = [] self.ref = "" def __getGitInfo(self): ''' ''' self.oldObject, self.newObject, self.ref = sys.stdin.readline().strip().split(' ') def __getPushInfo(self): ''' git show命令获取push作者,时间,以及文件列表 文件的路径为相对于版本库根目录的一个相对路径 ''' print(self.newObject) print(self.oldObject) if self.newObject.startswith("000000000"): exit(0) if self.oldObject.startswith("000000000"): exit(0) rev = subprocess.Popen('git rev-list '+self.newObject,shell=True,stdout=subprocess.PIPE) revList = rev.stdout.readlines() revList = [x.strip() for x in revList] #查找从上次提交self.oldObject之后还有多少次提交,即本次push提交的object列表 indexOld = revList.index(self.oldObject) pushList = revList[:indexOld] pushList.reverse() #tempdir = tempfile.mkdtemp('git_hook') tempdir = ('/tmp') # 循环获取每次提交的文件列表 for pObject in pushList: p = subprocess.Popen('git show '+pObject,shell=True,stdout=subprocess.PIPE) pipe = p.stdout.readlines() pipe = [x.strip() for x in pipe] for index, item in enumerate(pipe): if item.startswith("diff"): #验证是否java文件 file = item.strip("diff").strip() if not file.lower().endswith('.java'): continue filename = file.split('/')[-1] #git get Tree #content_hash = pipe[index+1].strip("index").strip()[10:16] if pipe[index+1].startswith("similarity"): s = pipe[index+4] i = s.index("..")+2 elif pipe[index+1].startswith("index"): s = pipe[index+1] i = s.index("..")+2 elif pipe[index + 1].startswith("new"): s = pipe[index + 2] i = s.index("..") + 2 else: continue print(s) content_hash = s[i:i+6] print(content_hash) content_p = subprocess.Popen('git cat-file -p '+content_hash,shell=True,stdout=subprocess.PIPE) cpipe = content_p.stdout.readlines() #print(cpipe) with open(os.path.join(tempdir, filename), 'w+') as fp: fp.writelines(cpipe) fp.close() self.handler_checkstyle(tempdir+'/'+filename) # checkstyle #self.handler_checkstyle(tempdir+"/") # 处理java文件 def handler_checkstyle(self, file): try: print(file) cmd = r'java -jar /data/gitlab.checkstyle/lib/checkstyle-8.20-all.jar -c /data/gitlab.checkstyle/style/checkstyle.xml '+file print(cmd) result = self.execCmd(cmd) print(result) a = 'ERROR' if a in result: #print(result) exit(1) except Exception, e: print('error message:' + e.message) exit(1) finally: os.system('rm {}'.format(file)) def execCmd(self, cmd): r = os.popen(cmd) text = r.read() r.close() return text def getGitPushInfo(self): self.__getGitInfo() self.__getPushInfo() if __name__ == "__main__": #print("argv: ", sys.argv) t = Trigger() t.getGitPushInfo() exit(0) ``` - 使用的jar包的位置:/data/gitlab.checkstyle/lib/checkstyle-8.20-all.jar - 使用的xml的位置:/data/gitlab.checkstyle/style/checkstyle.xml(内容和上面的style规则一致就行)