首页 > 其他分享 >阿里P3C-PMD配合Gitlab做编码规范检查

阿里P3C-PMD配合Gitlab做编码规范检查

时间:2024-05-16 10:19:00浏览次数:13  
标签:git java name repository P3C Gitlab jar echo PMD

1. Linux安装的Gitlab

参考这篇博文:Gitlab + P3C-PMD

1.1 P3C-PMD插件下载并打jar包

下载地址

本地文件:p3c-master.zip

本地jar包:p3c-pmd-2.1.1-jar-with-dependencies.jar

直接下载zip包,然后解压,进入p3c-pmd目录,cmd命令,执行如下mvn命令,编译Kotlin代码

mvn clean kotlin:compile package

待执行成功之后,打包

mvn package

打包完成之后可以在target目录下面看到3个jar包:

--- p3c-pmd-2.1.1.jar

--- p3c-pmd-2.1.1-jar-with-dependencies.jar

--- p3c-pmd-2.1.1-javadoc.jar

我们需要的是p3c-pmd-2.1.1-jar-with-dependencies.jar,接下来验证这个jar包,随便找一个java项目复制目录,例如:

D:\Code\Demo\src

切换至target目录,执行如下命令:

 java -cp p3c-pmd-2.1.1-jar-with-dependencies.jar net.sourceforge.pmd.PMD -d D:\Code\Demo\src -R rulesets/java/ali-comment.xml

如果出现代码格式不规范的提示,说明jar包打成功了。

1.2 Gitlab集成P3C-PMD

1.2.1 全局的设置

这个主要是利用的Gitlab的钩子(hooks),想深入了解的可以去官网看看文档。

官方文档

这里的设置是对所有项目起作用的,也就是全局的设置。

# 进入以下目录
cd /opt/gitlab/embedded/service/gitlab-shell/

# 创建hooks目录
mkdir hooks

# 进入hooks目录
cd hooks

# 创建一个pre-receive.d目录
mkdir pre-receive.d

# 进入pre-receive.d目录
cd pre-receive.d

# 将jar包上传进这个目录,改名
mv p3c-pmd-2.1.1-jar-with-dependencies.jar p3c-pmd-2.1.1.jar

# 创建一个名为pre-receive的文件
touch pre-receive

编辑pre-receive,填入以下内容:

#!/bin/sh
#
export LANG="en_US.UTF-8"
REJECT=0
# 这里替换成你的jdk目录
JAVA_HOME=/usr/local/java/jdk1.8.0_172
CHECK_JAR_HOME=/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d
# 要放过的代码仓库名称
array_pass_repository_name=("inner-test11.git" "inner-test21.git")
# 要放过的代码仓库组名称
array_pass_group_name=("framework1" "")

while read oldrev newrev refname; do
    if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
        oldrev="${newrev}^"
    fi
   
    # 跳过merge request 操作 
    operate_log=`git log ${oldrev}..${newrev} --pretty="%h ${refname} %B"`
    if [[ $operate_log =~ "merge request" ]];then
         echo "***merge request** continue"
         #exit 1
         continue
    fi

    files=`git diff --name-only ${oldrev} ${newrev} | grep -e ".java$"`

    if [ -n "$files" ];then
        TEMPDIR="tmp"
        for file in ${files}; do
            # 文件仓库地址
            file_repository_path=`pwd`/${file}
            # 利用字符串运算符 =~ 判断file_repository_path是否包含pass_repository_name
            #if [[ $file_repository_path =~ $pass_repository_name ]];then
            #     echo 'white list pass...repository name is '${pass_repository_name}
            #     continue
            #fi
            
            # 1.优先判断仓库组
            sub_path=${file_repository_path#*repositories/}
            echo "sub_path==="$sub_path
            group_name=${sub_path%%/*}
            echo "group_name====="$group_name
            # 判断白名单中是否包含要检查的仓库名称
            contain=$(echo "${array_pass_group_name[@]}" | grep -wq "$group_name" && echo "Yes" ||  echo "No")
            
            if [[ $contain == "Yes" ]]; then
                echo 'white list pass...repository group name is '${group_name}
                continue
            fi

            # 2.判断仓库名称
            sub_str=${file_repository_path%.git/*}
            echo "sub_str=="$sub_str
            repository_name=${sub_str##*/}
            echo "repository_name=="$repository_name
            name_contain=$(echo "${array_pass_repository_name[@]}" | grep -wq "$repository_name" && echo "Yes" ||  echo "No")
            
            if [[ $name_contain == "Yes" ]]; then
                echo 'white list pass...repository name is '${repository_name}
                continue
            fi
            
            mkdir -p "${TEMPDIR}/`dirname ${file}`" > /dev/null
            git show $newrev:$file > ${TEMPDIR}/${file}
        done;

        files_to_check=`find $TEMPDIR -name '*.java'`
        if [ ! -n "$files_to_check" ];then
            echo 'pass....'
        else
            echo -e "p3c-pmd check starting......"

            $JAVA_HOME/bin/java -cp $CHECK_JAR_HOME/p3c-pmd-2.1.1.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-orm.xml,rulesets/java/ali-other.xml,rulesets/java/ali-set.xml -f text

            REJECT=$?

            echo -e "p3c-pmd check end......"

            if [[ $REJECT == 0 ]] ;then
               echo -e "恭喜你代码通过质量检测!"
            else
               echo -e "请及时修改代码并再次尝试!!"
            fi

            rm -rf $TEMPDIR
        fi
    fi
done

exit $REJECT

保存退出,接下来是文件权限的设置:

# 为pre-receive文件赋予执行权限
chmod 776 pre-receive

# 为pre-receive.d 目录设置git权限
chown -R git:git /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d

至此,完成。

提交不符合规范的代码结果为:

修改完再提交:

1.2.2 针对单个项目的设置

首先要找到我们的项目仓库的位置,Gitlab仓库的目录是

var/opt/gitlab/git-data/repositories/{your_repository_dir}.git/

注意,Gitlab采用hash值来做仓库的目录,所以我们要先找到项目的Project ID

拿到这个ID之后,我们在进行hash运算,得到一个hash值,这个就是仓库的目录。

echo -n  ID | sha256sum

示例如下:

# 对35进行hash运算
echo -n  35 | sha256sum

# 得到的值是
9f14025af0065b30e47e23ebb3b491d39ae8ed17d33739e5ff3827ffb3634953  -

# 那么我们这个项目的仓库的目录就是(前面还有两个目录。9f和14,即前四位)
/var/opt/gitlab/git-data/repositories/\@hashed/9f/14/9f14025af0065b30e47e23ebb3b491d39ae8ed17d33739e5ff3827ffb3634953.git/

进入仓库之后,创建一个custom_hooks的文件夹,上传jar包到这里,或者还是将jar包放在1.2.1中的hooks文件夹里(推荐这个,比较好管理)。然后同1.2.1中一样,创建一个pre-receive,内容同上,然后改变文件和文件夹的读写权限。

chmod 776 pre-receive

chown -R git:git /var/opt/gitlab/git-data/repositories/\@hashed/86/e5/86e50149658661312a9e0b35558d84f6c6d3da797f552a9657fe0558ca40cdef.git/custom_hooks

至此,单个项目的配置完成。

2. docker安装的Gitlab

2.1 jar包同1.1

2.2 集成P3C-PMD

2.2.1 docker内安装jdk

# 获取docker容器id
docker ps

# 复制jdk目录到docker容器内
docker cp <path to jdk gz file>/jdk1.8.0_11 <容器名称或者ID>:/mnt/soft

# 例子
# docker cp /soft/jdk1.8.0_11 131514ad1c3f:/mnt/soft

# 进入容器
docker exec -it <容器名称或者ID> bash

# 设置环境变量
vi ~/.bashrc

export JAVA_HOME=/mnt/soft/jdk1.8.0_11 ## 这里要注意目录要换成自己解压的jdk 目录
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

# 刷新配置文件
source ~/.bashrc

# 验证JDK版本
java -version

2.2.2 配置P3C-PMD

2.2.2.1 全局配置

同在Linux环境下一样,都是利用的hooks机制,同样的,创建目录、文件并上传jar包(这里需要复制到docker容器内)。

# 复制文件至docker容器
docker cp /soft/p3c-pmd-2.1.1.jar <容器名称或者ID>:/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d

接下来步骤同上,但是pre-receive文件有一些改变,完整的文件内容如下:

#!/bin/bash
#
export LANG="C.UTF-8"
REJECT=0
# 这里替换成你的jdk目录
JAVA_HOME=/mnt/soft/jdk1.8.0_11
CHECK_JAR_HOME=/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d
# 要放过的代码仓库名称
array_pass_repository_name=("inner-test11.git" "inner-test21.git")
# 要放过的代码仓库组名称
array_pass_group_name=("framework1" "")

while read oldrev newrev refname; do
    if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
        oldrev="${newrev}^"
    fi
   
    # 跳过merge request 操作 
    operate_log=`git log ${oldrev}..${newrev} --pretty="%h ${refname} %B"`
    if [[ $operate_log =~ "merge request" ]];then
         echo "***merge request** continue"
         #exit 1
         continue
    fi

    files=`git diff --name-only ${oldrev} ${newrev} | grep -e ".java$"`

    if [ -n "$files" ];then
        TEMPDIR="tmp"
        for file in ${files}; do
            # 文件仓库地址
            file_repository_path=`pwd`/${file}
            # 利用字符串运算符 =~ 判断file_repository_path是否包含pass_repository_name
            #if [[ $file_repository_path =~ $pass_repository_name ]];then
            #     echo 'white list pass...repository name is '${pass_repository_name}
            #     continue
            #fi
            
            # 1.优先判断仓库组
            sub_path=${file_repository_path#*repositories/}
            echo "sub_path==="$sub_path
            group_name=${sub_path%%/*}
            echo "group_name====="$group_name
            # 判断白名单中是否包含要检查的仓库名称
            contain=$(echo "${array_pass_group_name[@]}" | grep -wq "$group_name" && echo "Yes" ||  echo "No")
            
            if [[ $contain == "Yes" ]]; then
                echo 'white list pass...repository group name is '${group_name}
                continue
            fi

            # 2.判断仓库名称
            sub_str=${file_repository_path%.git/*}
            echo "sub_str=="$sub_str
            repository_name=${sub_str##*/}
            echo "repository_name=="$repository_name
            name_contain=$(echo "${array_pass_repository_name[@]}" | grep -wq "$repository_name" && echo "Yes" ||  echo "No")
            
            if [[ $name_contain == "Yes" ]]; then
                echo 'white list pass...repository name is '${repository_name}
                continue
            fi
            
            mkdir -p "${TEMPDIR}/`dirname ${file}`" > /dev/null
            git show $newrev:$file > ${TEMPDIR}/${file}
        done;

        files_to_check=`find $TEMPDIR -name '*.java'`
        if [ ! -n "$files_to_check" ];then
            echo 'pass....'
        else
            echo -e "p3c-pmd check starting......"

            $JAVA_HOME/bin/java -cp $CHECK_JAR_HOME/p3c-pmd-2.1.1.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-orm.xml,rulesets/java/ali-other.xml,rulesets/java/ali-set.xml -f text

            REJECT=$?

            echo -e "p3c-pmd check end......"

            if [[ $REJECT == 0 ]] ;then
               echo -e "恭喜你代码通过质量检测!"
            else
               echo -e "请及时修改代码并再次尝试!!"
            fi

            rm -rf $TEMPDIR
        fi
    fi
done

exit $REJECT

区别的地方在于:

  1. !/bin/bash

  2. 字符集定义 export LANG="C.UTF-8"
2.2.2.2 单个项目设置

同1.2.2,找到仓库位置,操作一致,注意文件内容是2.2.2.1中的。

参考文章:

  1. Docker容器中安装JDK

  2. 如何在Linux下安装Docker

  3. docker下gitlab安装配置使用(完整版)

  4. docker常规操作

标签:git,java,name,repository,P3C,Gitlab,jar,echo,PMD
From: https://www.cnblogs.com/datangguanjunhou/p/18195444

相关文章

  • gitlab备份
    gitlab备份cronteb-e配置:02***/root/gitlab.sh03***/var/opt/gitlab/backups/gitlabbak.shgitlab.sh脚本(本机备份)#!/bin/bash/opt/gitlab/bin/gitlab-rakegitlab:backup:createCRON=1 gitlabbak.sh脚本,把备份复制到192.168.0.168设备上进行异地备份(两台设备......
  • GitLab 管理 NuGet 包
    1概览在服务器上构建项目时,需要引用nuget.org之外的包,如公司内部开发的、第三方未发布到nuget.org上的。怎么办?GitLab提供了PackageRegistry来解决这个问题。2上传NuGet包到指定项目中新建或使用一个已有项目,作为存放NuGet包的项目,为其他需要引用对应NuGet......
  • Docker下搭建gitlab
    docker安装流程获取gitlab(社区版)--已有镜像时,可跳过此步dockerpullgitlab/gitlab-ce:latest创建本地卷用于保存gitlab数据e:\dockerdata\config\logs\data运行dockerrun--detach--hostnamexxxx.com--publish443:443--publi......
  • gitlab迁移到gitea可行方案
    gitea与gitlab优势比较明显,实际占用资源占比大约1:4gitlab迁移所有仓库到gitea,目前有自动化脚本,但是有个bug需要修复原始自动化迁移工具https://github.com/h44z/gitlab_to_gitea遇到的问题:importfailed:{"message":"Authenticationfailed:Clone:exitstatus128-rem......
  • gitlab权限管理,远程仓库(旧)
    gitlab权限管理,远程仓库(旧)6.gitlab权限管理,远程仓库在组中设置的权限会继承到组中的所有项目中在项目中添加权限只影响该项目创建后项目中的成员后,管理员手动设置成员密码(8位以上),成员登陆后系统会要求重设密码dev1登陆,添加host6的公钥,yuminstallgit,[email protected]......
  • 6-gitlab备份和恢复
    6.gitlab备份和恢复建议备份策略:本地保留3-7天,异地永久备份查看版本cat/etc/redhat-releasecat/opt/gitlab/embedded/service/gitlab-rails/VERSION备份修改配置文件vim/etc/gitlab/gitlab.rbgitlab_rails['manage_backup_path']='true'gitlab_rails['backup_path......
  • GitLab 管理 NuGet 包
    1概览在服务器上构建项目时,需要引用nuget.org之外的包,如公司内部开发的、第三方未发布到nuget.org上的。怎么办?GitLab提供了PackageRegistry来解决这个问题。2上传NuGet包到指定项目中新建或使用一个已有项目,作为存放NuGet包的项目,为其他需要引用对应NuGet......
  • 在Windows运行Gitlab Runner对.NET Framework 4.6.1旧项目自动执行单元测试
    摘要本文介绍了GitlabRunner如何在Windows服务器上调用vstest.console.exe,对旧的项目基于.NETFramework4.6.1的项目,自动执行单元测试。改造旧版本的.csproj文件改造成功后,完整的.csproj文件如下:<ProjectSdk="Microsoft.NET.Sdk"> <PropertyGroup><ProjectG......
  • 在Windows运行Gitlab Runner对.NET Framework 4.6.1旧项目自动执行单元测试
    摘要本文介绍了GitlabRunner如何在Windows服务器上调用vstest.console.exe,对旧的项目基于.NETFramework4.6.1的项目,自动执行单元测试。改造旧版本的.csproj文件改造成功后,完整的.csproj文件如下:<ProjectSdk="Microsoft.NET.Sdk"> <PropertyGroup><ProjectG......
  • 在Gitlab Runner中调用Web Api写入Directory.Build.props需要的版本号文件
    摘要本文介绍了在Windows上的GitlabRunner,如何调用webapi更新版本号定义文件。PowerShellfunctionUpdate-Version{ param( [string]$WEB_API_URL, [string]$NAMESPACE, [string]$VERSION_ID )echo"能生成或写入.props文件的webapi的网站地址:"$WEB_API_URLe......