微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GitLab服务端集成CheckStyle实现代码自动审核

1. 概述

对于Git通过Hook实现静态代码检测,大致分为两个方向:

1>借助Client-Side-Hook来实现。

方法对应于研发人员工作机上的${PROJECT_ROOT}/.git/hooks/pre-commit脚本实现。

2>借助Server-Side-Hook来实现。

方法分为2个方面,一个是全局性配置(下面会详细介绍),一个是对应对单独项目进行配置,此方法对应于Git服务端的
/var/opt/gitlab/git-data/repositories/<group>/<project>.git/custom_hooks/pre-receive脚本。

相比较之下,两种实现方式之中,第二种方式有点更明显,其无需研发人员进行任何的本地操作,这里详细讲解gitlab的全局配置。

3>使用关键组件包括

checkstyle8.17+python2.7.5+jdk1.8

python 的版本不能超过3.0

Jdk 版本最低为1.8

2.操作步骤

2.1:上传文件

登录Gitlab服务

1.创建文件路径,执行命令:

mkdir -p /data/gitlab.checkstyle

2.进入文件

cd /data/gitlab.checkstyle

3.将checkstyle.xml和checkstyle-8.17-all.jar 文件上传到gitlab.checkstyle

4.验证是否正确

可执行命令:

java -jar /data/gitlab.checkstyle/checkstyle-8.17-all.jar -c/data/gitlab.checkstyle/checkstyle.xml /data/gitlab.checkstyle/TestController.java

如有些类似输出内容即表示环境正确。

TestController.java文件可自行上传

checkstyle.xml文件可自行网上查找,可使用谷歌或阿里的都可以。

图片

2.1.配置gitlab全局钩子

1.创建自定义全局钩子目录

cd /opt/gitlab/embedded/service/gitlab-shell/

mkdir custom_hooks

2.指定全局自定义钩子目录

修改 /etc/gitlab/gitlab.rb 配置文件中的配置项:gitlab_shell['custom_hooks_dir']内容为:

/opt/gitlab/embedded/service/gitlab-shell/custom_hooks

内容为:

图片

修改内容为:
/opt/gitlab/embedded/service/gitlab-shell/custom_hooks

vi /etc/gitlab/gitlab.rb

图片

3.使自定义内容生效

操作完成后,执行命令使配置生效:

sudo gitlab-ctl reconfigure

图片

2.3上传代码规范检查脚本

1.进入全局自定义钩子目录下:

cd /opt/gitlab/embedded/service/gitlab-shell/custom_hooks

2.创建pre-receive.d文件

mkdir pre-receive.d

cd pre-receive.d

3.上传附件中的pre-receive文件到pre-receive.d文件目录下并赋予可执行权限

chmod +777 pre-receive

4.pre-receive脚本内容为:

#!/usr/bin/python
#coding=utf-8
import os
import sys
import subprocess
import tempfile
import shutil
__author__ = "lance"
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作者,时间,以及文件列表
       文件的路径为相对于版本库根目录的一个相对路径
       '''
       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()
       # temp file
       tempdir = tempfile.mkdtemp('git_hook')
       #循环获取每次提交的文件列表
       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]
           #print("===>",pipe)   
           #验证是否java文件
           file = pipe[6].strip("diff").strip()
           if not file.lower().endswith('.java'):
              continue
       filename = file.split('/')[-1]
       #git get Tree
       content_hash = pipe[7].strip("index").strip()[9:16]
       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)
       #self.handler_checkstyle(tempdir+"/"+content_hash+'.java')      
       # checkstyle    
       self.handler_checkstyle(tempdir)
   def getGitPushInfo(self):
       self.__getGitInfo()
       self.__getPushInfo()

 # 处理java文件 
   def handler_checkstyle(self, file):
    try:
       cmd = r'java -jar /data/gitlab.checkstyle/lib/checkstyle-8.17-all.jar -c /data/gitlab.checkstyle/style/checkstyle.xml '+file+'/'
       #print(cmd)
       result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       rpipe = result.stdout.readlines()
       if len(rpipe)>2:
           print(rpipe)
       exit(1)
    finally:
       shutil.rmtree(file)
       #pass          

if __name__ == "__main__":
   #print("argv: ", sys.argv)
   t = Trigger()
   t.getGitPushInfo()    
   exit(0)

3.验证

对于不合规的内容输出异常提示

图片

如果想了解单独配置和全局配置下想单独排查某项目的步骤,欢迎联系。

以上为全部内容

欢迎关注10W+的微信公众号:

 

技术难点欢迎咨询,如有需要加我微信:1106915848。

星光不问赶路人,时光不负有心人

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐