美文网首页
gitlab集成阿里p3c代码规约检测

gitlab集成阿里p3c代码规约检测

作者: 鬼谷子的码农之路 | 来源:发表于2020-04-10 19:29 被阅读0次

    Why

    在公司业务代码review过程中,发现有许多开发人员在开发的时候没有加入注释,命名也有许多不规范的,还有一些其它规范的问题,代码质量参差不齐,也会严重影响后续的维护。虽然现行的有许多的代码检查工具,但是都是非强制的,急需一种强制校验的方式来规避以上的问题,所以我们挑选了阿里的p3c代码规范,做了二开,保留了一些初期基础的代码规范,同时加入了一些与公司要求相关的检查点。我们把这个检查插件加入到了gitlab中,在提交代码时进行强制的校验,检查不通过的不允许提交。我们在gitlab的git-hooks中通过pre-receive来对push的请求进行拦截。

    How

    修改p3c-pmd

    基于开源的alibaba-p3c[点击访问],我们clone到本地,修改其中的p3c-pmd包

    image

    我们可以看到它的rulesets下有许多的规则,我们添加了我们自己的”customize.xml“规则,同时我们需要根据实际的需求去挑选原有的规则哪些是必须的。所以我们根据这些规则抽出了一个新的文件”ali-p3c.xml“,其中我们会排除一些非必须的规则。

    
    <?xml version="1.0"?>
    
    <ruleset name="AlibabaJavaComments" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    
        xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
    
        <description>futuremarket Java Comments
    
        <rule ref="rulesets/java/ali-comment.xml" >
    
            <exclude name="EnumConstantsMustHaveCommentRule"/>
    
            <exclude name="AvoidCommentBehindStatementRule"/>
    
            <exclude name="RemoveCommentedCodeRule"/>
    
        <rule ref="rulesets/java/ali-concurrent.xml" language="">
    
            <exclude name="ThreadPoolCreationRule"/>
    
            <exclude name="AvoidUseTimerRule"/>
    
            <exclude name="AvoidCallStaticSimpleDateFormatRule"/>
    
            <exclude name="ThreadLocalShouldRemoveRule"/>
    
            <exclude name="AvoidConcurrentCompetitionRandomRule"/>
    
            <exclude name="CountDownShouldInFinallyRule"/>
    
            <exclude name="LockShouldWithTryFinallyRule"/>
    
        <rule ref="rulesets/java/ali-constant.xml" >
    
        <rule ref="rulesets/java/ali-exception.xml" >
    
            <exclude name="MethodReturnWrapperTypeRule"/>
    
        <rule ref="rulesets/java/ali-flowcontrol.xml" >
    
            <exclude name="AvoidNegationOperatorRule"/>
    
        <rule ref="rulesets/java/ali-naming.xml" >
    
            <exclude name="AbstractClassShouldStartWithAbstractNamingRule"/>
    
            <exclude name="ExceptionClassShouldEndWithExceptionRule"/>
    
            <exclude name="TestClassShouldEndWithTestNamingRule"/>
    
            <exclude name="BooleanPropertyShouldNotStartWithIsRule"/>
    
            <exclude name="ArrayNamingShouldHaveBracketRule"/>
    
        <rule ref="rulesets/java/ali-oop.xml" >
    
            <exclude name="PojoMustUsePrimitiveFieldRule"/>
    
            <exclude name="PojoNoDefaultValueRule"/>
    
            <exclude name="PojoMustOverrideToStringRule"/>
    
            <exclude name="StringConcatRule"/>
    
        <rule ref="rulesets/java/ali-orm.xml" >
    
            <exclude name="IbatisMethodQueryForListRule"/>
    
        <rule ref="rulesets/java/ali-other.xml" >
    
            <exclude name="AvoidPatternCompileInMethodRule"/>
    
            <exclude name="AvoidApacheBeanUtilsCopyRule"/>
    
            <exclude name="AvoidMissUseOfMathRandomRule"/>
    
            <exclude name="AvoidDoubleOrFloatEqualCompareRule"/>
    
        <rule ref="rulesets/java/ali-set.xml" >
    
            <exclude name="ClassCastExceptionWithToArrayRule"/>
    
            <exclude name="UnsupportedExceptionWithModifyAsListRule"/>
    
            <exclude name="ClassCastExceptionWithSubListToArrayListRule"/>
    
            <exclude name="ConcurrentExceptionWithModifyOriginSubListRule"/>
    
            <exclude name="DontModifyInForeachCircleRule"/>
    
            <exclude name="CollectionInitShouldAssignCapacityRule"/>
    
        <rule ref="rulesets/java/customize.xml"/>
    
    </ruleset>
    
    

    以上,我们完成了我们规则的定制,maven打包得到我们需要的jar-with-dependencies包

    mvn clean package -Dmaven.test.skip=true
    

    添加git-hooks脚本

    gitlab版本不一样git-hooks路径可能会不一样,公司使用的是GitLab Community Edition 12.2.1,我本地安装的是# GitLab Community Edition 12.8.5,都会比较新的版本。
    进入到目录/opt/gitlab/embedded/service/gitaly-ruby/git-hooks,修改脚本pre-receive

    #!/bin/bash
    export LANG="zh_CN.UTF-8"
    export JAVA_HOME=/home/jdk1.8.0_202
    export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$PATH:$JAVA_HOME/bin:
    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/gitlab/embedded/service/gitaly-ruby/git-hooks/p3c-pmd-2.0.1-jar-with-dependencies.jar net.sourceforge.pmd.PMD -d $TEMPDIR -R rulesets/ali-p3c.xml -f text -shortnames
    
             REJECT=$?
            echo "reject = "$REJECT
              if [ $REJECT = 0 ] ;then
                echo "恭喜你代码通过质量检测!"
        elif [ $committer = 'xxx@xxx.com' ]; then
          echo "在白名单中,临时允许通过"
                REJECT=0
              else  echo  "请及时修改代码并再次尝试!"
              fi
    
            rm -rf $TEMPDIR
        fi
    done
    
    exit $REJECT
    

    需要关注

    java -Dpmd.language=en -cp /opt/gitlab/embedded/service/gitaly-ruby/git-hooks/p3c-pmd-2.0.1-jar-with-dependencies.jar net.sourceforge.pmd.PMD -d $TEMPDIR -R rulesets/ali-p3c.xml -f text -shortnames
    

    这个代码指定的规则文件ulesets/ali-p3c.xml是我们前面抽取出来的。如果你不需要单独抽取的话,可以指定p3c-pmd下的所有规则文件。
    脚本的修改不需要重启gitlab,是实时生效的。一切OK,下面我们可以提交文件来测试下!!

    测试

    我们把一个java文件去掉@author的javadoc注释,我们坐git push的时候得到如下信息:

    remote: Apr 10, 2020 11:08:36 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: src/main/java/com/example/demo/provider/MessageProviderImpl.java:15:    [MessageProviderImpl] should have @author javadoc
    remote: reject = 4
    remote: 请及时修改代码并再次尝试!
    To http://localhost:32770/root/demo-provider.git
     ! [remote rejected] master -> master (pre-receive hook declined)
    error: failed to push some refs to 'http://localhost:32770/root/demo-provider.git'
    
    

    根据提示,修改,再次push:

    remote: Apr 10, 2020 11:17:10 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: reject = 0
    remote: 恭喜你代码通过质量检测!
    To http://localhost:32770/root/demo-provider.git
       5d077e5..96cc722  master -> master
    
    

    这样我们就完成了集成代码检查工具到gitlab的工作。
    关于集成到gitlab的这段,我们参考了【如何生成整合了阿里巴巴JAVA编码规范的PMD包配合GitLab提升团队代码质量】这篇文章,但是可能是因为gitlab版本不同,我们做了简单的修改。这里也感谢@背包客要背包的分享

    更近一步

    但是提交再检测毕竟有些滞后,开发人员更多的时候想要再开发阶段就能够发现不符合规范的问题,ali-p3c规范有idea和eclipse插件,我们需要构建出独立的插件出来提供给开发使用。这个我们也在集成到gitlab的时候一起提供给了公司所有的开发同学。关于如何二开插件的话题我们下一章再继续讨论了,有兴趣的朋友也可以自己研究一样。

    相关文章

      网友评论

          本文标题:gitlab集成阿里p3c代码规约检测

          本文链接:https://www.haomeiwen.com/subject/rsjdmhtx.html