by 007

Gitlab集成阿里p3c插件实现代码检测

2020.11.06

1.说明

使用阿里开源的项目 p3c 对gitlab上项目进行代码(java)检测,新版gitlab改动较大,相关文档较少,本文整理官档和网友脚本希望对大家有个引导作用,避免踩坑。

2.p3c编译及文件准备

2.1 jar包 编译过程省略,我们得到jar包:

p3c-pmd/target/p3c-pmd-2.0.1-jar-with-dependencies.jar

2.2 xml规则文件

[root@localhost p3c]# ll p3c-pmd/target/classes/rulesets/java/
总用量 68
-rw-r--r-- 1 root root  4492 6月  23 14:25 ali-comment.xml
-rw-r--r-- 1 root root 10851 6月  23 14:25 ali-concurrent.xml
-rw-r--r-- 1 root root  1445 6月  23 14:25 ali-constant.xml
-rw-r--r-- 1 root root  3745 6月  23 14:25 ali-exception.xml
-rw-r--r-- 1 root root  2658 6月  23 14:25 ali-flowcontrol.xml
-rw-r--r-- 1 root root  5159 6月  23 14:25 ali-naming.xml
-rw-r--r-- 1 root root  4514 6月  23 14:25 ali-oop.xml
-rw-r--r-- 1 root root   636 6月  23 14:25 ali-orm.xml
-rw-r--r-- 1 root root  4573 6月  23 14:25 ali-other.xml
-rw-r--r-- 1 root root  4130 6月  23 14:25 ali-set.xml

2.3 文件目录 我们需要把准备好的jar包和xml规则文件放到我们规划好的目录下,这里我们放到gitlab服务器"/opt/git-hooks/“目录。

目录结构如下:

[root@localhost ~]# tree /opt/git-hooks/
/opt/git-hooks/
├── p3c-pmd-2.0.1-jar-with-dependencies.jar
└── rulesets
    ├── ali-comment.xml
    ├── ali-concurrent.xml
    ├── ali-constant.xml
    ├── ali-exception.xml
    ├── ali-flowcontrol.xml
    ├── ali-naming.xml
    ├── ali-oop.xml
    ├── ali-orm.xml
    ├── ali-other.xml
    └── ali-set.xml

1 directory, 11 files

3.gitlab配置

在配置gitlab之前我们需要了解下gitlab仓库数据存储位置:

[root@localhost ~]# ll /var/opt/gitlab/git-data/repositories
总用量 8
drwxr-sr-x   3 git root 4096 12月 26 2019 +gitaly
drwxr-s--- 106 git root 4096 6月  29 10:05 @hashed

由于项目目录名称都是经过hash的,我们并不能直接从目录名称看出来仓库及组和项目对应的目录。所以当我们需要对某个项目进行添加规则时需要找到项目对应的hash目录。具体的项目hash目录可通过gitlab管理员进入项目管理后台,点开对应的项目即可看到Gitaly relative path,此处即为对应项目hash目录名称。 在这里插入图片描述 进入到项目目录下 /var/opt/gitlab/git-data/repositories/"Gitaly relative path” 创建目录:custom_hooks/pre-receive.d 创建脚本文件:custom_hooks/pre-receive.d/pre-receive

// pre-receive文件注意: 01.文件名无后缀 02.文件属组(chown -R git:root custom_hooks ) 03.可执行(chmod 777 custom_hooks/pre-receive.d/pre-receive )

pre-receive脚本内容如下:

#!/bin/bash
export JAVA_HOME=/opt/jdk1.8.0_111
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

REJECT=0

while read oldrev newrev refname; do
    if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
        oldrev="${newrev}^"
    fi
    committer=`git log -1 $newrev --pretty=%ce`
    files=`git diff --name-only ${oldrev} ${newrev}  | grep -e ".java$"`
    echo $committer
    if [ -n "$files" ]; then
        TEMPDIR="tmp"
        for file in ${files}; do
            mkdir -p "${TEMPDIR}/`dirname ${file}`" >/dev/null
            git show $newrev:$file > ${TEMPDIR}/${file}
        done;

        files_to_check=`find $TEMPDIR -name '*.java'`

        java -Dpmd.language=en -cp /opt/git-hooks/p3c-pmd-2.0.1-jar-with-dependencies.jar net.sourceforge.pmd.PMD -d $TEMPDIR -R /opt/git-hooks/rulesets/ali-comment.xml,/opt/git-hooks/rulesets/ali-concurrent.xml,/opt/git-hooks/rulesets/ali-constant.xml,/opt/git-hooks/rulesets/ali-exception.xml,/opt/git-hooks/rulesets/ali-flowcontrol.xml,/opt/git-hooks/rulesets/ali-naming.xml,/opt/git-hooks/rulesets/ali-oop.xml,/opt/git-hooks/rulesets/ali-orm.xml,/opt/git-hooks/rulesets/ali-other.xml,/opt/git-hooks/rulesets/ali-set.xml -f text -shortnames

         REJECT=$?
        echo "reject = "$REJECT
          if [ $REJECT = 0 ] ;then
            echo "恭喜你代码通过质量检测!"
    elif [ $committer = 'admin@domain.com' ]; then
      echo "在白名单中,临时允许通过"
            REJECT=0
          else  echo  "请及时修改代码并再次尝试!"
          fi

        rm -rf $TEMPDIR
    fi
done

exit $REJECT

文件创建完成后立即生效(不需要重启gitlab服务)。

4.测试

使用无作者注释的代码提交测试验证。

git add .; git commit -m 'test'; git push origin master

remote: Jul 02, 2020 11:28:38 AM net.sourceforge.pmd.PMD processFiles
remote: WARNING: This analysis could be faster, please consider using Incremental Analysis: https://pmd.github.io/pmd-6.15.0/pmd_userdocs_incremental_analysis.html
remote: microservice-manager-provide/src/main/java/cn/mwcare/MicroServiceManagerApplication.java:21:	javadoc of [MicroServiceManagerApplication] should contain @author tag
remote: reject = 4
remote: 请及时修改代码并再次尝试!