SVN代码风格自动检查

在项目开发过程中,为了能够使团队成员的代码风格保持一致,我们考虑在SVN服务端搭建一个代码风格校验环境。其作用就是在SVN提交代码时,强制检查代码风格,拒绝那些不符合要求的代码。在搭建环境的过程中遇到了各种各样的问题,走了不少弯路,而且网上关于这方面的资料较少且不全面。经过多次尝试和调试终于搭建成功,现将完整过程记录下来,以供参考。

在这里我们采用的解决方案是:SVN服务端 + svnchecker-0.3 + checkstyle-5.3。其中需要特别注意的是:svnchecker-0.3依赖于Python2,而且它和高版本的checkstyle不兼容。svnchecker项目中存在一些bug需要我们自己修改,后面会介绍。

  • 工作原理:
  1. 使用CheckStyle定义Java代码的风格规范
  2. 使用svnchecker调用CheckStyle定义的规范进行检查
  3. 使用svn的钩子程序在代码提交前执行svnchecker
  • 安装准备:

  • 机器环境:CentOS release 6.5 (Final)Python2.6JDK1.8.0_92(不影响环境搭建)、svn 1.6.11

  • 软件下载:

    • CheckStyle:
      项目主页:http://checkstyle.sourceforge.net/
      下载页面:http://sourceforge.net/projects/checkstyle/files/
      百度云盘:checkstyle-5.3.tar.gz 密码: smpx
      下载之后,解压,然后将里面的jar包加上可执行权限
    • svnchecker:
      项目主页:http://svnchecker.sourceforge.net/ 和 http://svnchecker.tigris.org/
      下载页面:http://svnchecker.sourceforge.net/download.php
      百度云盘:svnchecker-0.3.tar.gz 密码: tu9r (已修复svnchecker中存在的bug)
      下载之后,解压,然后将里面的py文件加上可执行权限
  • 安装步骤:

  • 配置checkstyle.xml文件
    确定一个适合本团队的checkstyle.xml是非常重要的,它直接决定了代码风格校验的效果。
    checkstyle.xml的具体书写规则以及它的能力与限制,请参考:http://checkstyle.sourceforge.net/checks.html。本人总结整理的checkstyle.xml 密码: pxuj。

  • 配置svncheckerconfig.ini文件
    svncheckerconfig.ini文件的具体格式是由Python的ConfigParser类定义的标准配置文件格式,非常容易出错,因此要小心书写。如果该配置文件存在格式错误,在运行时会提示找不到配置文件。
    svncheckerconfig.ini既可放在svnchecker的安装目录之下,也可以放在hooks目录之下。针对于“在svnchecker目录下可以起到全局作用,在hooks目录下只对该版本库起作用”的说法,本人亲测并不可信。
    svncheckerconfig.ini文件在官方的svnchecker中默认是不存在的,需要自己创建并编辑,文件的具体内容如下:

    ```
    [DEFAULT]
    Main.PreCommitChecks=Checkstyle
    Main.Regex=
    Checkstyle.FailureHandlers=Console
    Checkstyle.Java=/usr/local/jdk/jdk1.8.0_92/bin/java
    Checkstyle.Classpath=/opt/checkstyle-5.3/checkstyle-5.3-all.jar
    Checkstyle.ConfigFile=/opt/checkstyle-5.3/pxjy_checks.xml
    Checkstyle.CheckFiles=^geeker/wxf-common/.*\.java$|^svntest/.*\.java$|^geeker/geeker-common/.*\.java$
    Checkstyle.IgnoreFiles=
    ```
    **说明:**
    1. `[DEFAULT]`:必须配置,svnchecker会根据该标签进行配置信息的读取,若不配置,运行时会提示找不到配置文件
    2. `Main.PreCommitChecks`:配置为`Checkstyle`即可
    3. `Main.Regex`:不用配置,但必须存在。若配置则报错,原因未知。
    4. `Checkstyle.FailureHandlers`:配置为`Console`即可
    5. `Checkstyle.Java`:配置为`%JAVA_HOME%/bin/java`
    6. `Checkstyle.Classpath`:`checkstyle-5.3-all.jar`文件位置
    7. `Checkstyle.ConfigFile`:`checkstyle.xml`文件的位置
    8. `Checkstyle.CheckFiles`:配置要检查的文件,内容为正则表达式。格式如:`^geeker/geeker-web/.*\.java$|^geeker/geeker-common/.*\.java$`,表达式中`geeker`为版本库名,`geeker-web`和`geeker-common`为该版本库下的两个项目。所以我们可以通过这里的正则表达式来控制SVN服务器对哪个版本库或哪个项目进行风格检查。
    9. `Checkstyle.IgnoreFiles`:配置过滤文件,内容为正则表达式
    
  • 修改SVN的pre-commit脚本
    首先进入到版本库hooks目录下,然后将文件pre-commit.tmpl重命名为pre-commit并赋予可执行权限。在pre-commit文件中进行如下修改:
    在这里插入图片描述

# 添加的内容(注意:Main.py文件的路径及*.py文件的执行权限)
/opt/svnchecker-0.3/Main.py PreCommit $1 $2 || exit 1
  • 修改svnchecker中存在的bug
    svnchecker工程已停止维护,所以对于bug需要自己修改。如果你的svnchecker是从上面提供的百度网盘中下载的那么你不需要进行如下修改。

    • 对于svn路径有空格会找不到文件的bug,修改svnchecker文件checks/checkstyle.py,代码块如下:
       if len(files) == 0:
           return ("", 0)
       try:
           #Process.execute(command + " ".join(files))
           for file in files:
               command += '"' + file + '" '
           Process.execute(command)
    
    • 返回错误信息太多导致Network connection closed unexpectedly的问题,修改checks/checkstyle.py,代码块如下:
       except Process.ProcessException, e:
           msg = "发现编码风格错误:\n\n"
           msg += e.output + " "
           if len(msg) > 6000:
               msg = msg[:6000]
           msg += ""
           return (msg, 1)
    
        注意:如果你讲checkstyle.py文件中的`Coding style errors found`翻译成了中文,那么你还需要在checkstyle.py文件中进行下面的配置,否则会报错。
        1. 在文件头添加`# -*- coding:UTF-8 -*-`
        2. 引入sys
        ```
        import sys
        ```
        3. 在run方法中添加如下内容
        ```粗体文本
        reload(sys)
        sys.setdefaultencoding('utf-8')
        ```
    
  • 校验反馈乱码问题
    通过上面的配置,我们的环境基本上算是完成了,但是如果你在checkstyle.xml文件中对校验返回信息进行了中文国际化,那么当你在使用SVN提交文件时遇到风格错误,反馈信息中就会出现中文乱码问题。
    具体原因应该是,CheckStyle将风格错误信息输出到svnchecker时产生乱码,所以对于这样的问题就需要我们自己修改两者之间的数据传输方式。我采取的解决方案是在CheckStyle中将风格错误信息转化为Unicode编码,svnchecker接收到以后再将Unicode装换为UTF-8格式的中文。具体修改如下:

    1. 修改CheckStyle的源代码
      修改com.puppycrawl.tools.checkstyle.DefaultLogger.java中的public void addError(AuditEvent aEvt)方法,将该方法中的输出信息转为Unicode编码。修改后将代码打包并替换checkstyle-5.3-all.jar中的对应文件。
    2. 修改svnchecker的源代码
      依然是修改checks/checkstyle.py文件,修改如下:在这里插入图片描述

    通过上面的修改可以完美解决eclipse、SVN客户端的乱码问题,但是IntelliJ IDEA还存在乱码问题。我的解决方法是找到IntelliJ Idea的File->Settings->Editor->File Encodings的Global Encoding配置成GBK。

  • 提交多个文件时报错问题
    在使用过程中发现,如果提交多个java文件到SVN时,会提交失败。原因是svnchecker工具将我们提交的文件地址拼接成了一个字符串并传递给checkstyle,从而导致checkstyle无法识别、处理提交的多个文件。所以对于这个问题我们完全可以通过修改checkstyle的代码进行修复(直接修改svnchecker的代码代价较大,因为看不懂phony代码)。
    通过上面的分析知道,提交多个java文件到SVN时,checkstyle接收到的是多个java文件的路径地址字符串。因此我们只需将这个字符串进行拆分就可以了。具体修改如下:

    1. 修改CheckStyle的源代码
      修改com.puppycrawl.tools.checkstyle.Main.java中的private static List<File> getFilesToProcess(CommandLine aLine)方法,修改后的方法如下:
    private static List<File> getFilesToProcess(CommandLine aLine){
        final List<File> files = Lists.newLinkedList();
        if (aLine.hasOption("r")) {
            final String[] values = aLine.getOptionValues("r");
            for (String element : values) {
                traverse(new File(element), files);
            }
        }
    
        final String[] remainingArgs = aLine.getArgs();
        for (String element : remainingArgs) {
            File elementFile = new File(element);
            if(elementFile.canRead()){
                files.add(elementFile);
            } else{
                String[] fileNames = element.split("\\.java");
                for(String file : fileNames){
                    File f = new File(file + ".java");
                    if(f.isFile()){
                        files.add(f);
                    }
                }
            }
        }
    
        if (files.isEmpty() && !aLine.hasOption("r")) {
            System.out.println("Must specify files to process");
            usage();
        }
        return files;
    }
    
     修改后将代码打包并替换checkstyle-5.3-all.jar中的对应文件。这里我提供一下自己修改的jar包:[checkstyle-5.3-all.jar](https://pan.baidu.com/s/1RtCovGEEauNuAnhVzqfs8A)  密码: 4zfv
    
  • 相关推荐
    为配合SVN服务端的校验检查我们最好在本地开发工具中也配置同样的代码风格检验,从而做到将不符合规范的代码扼杀在摇篮中。
    在Eclipse上安装和使用Checkstyle
    在IDEA上安装和使用Checkstyle

  • 其他相关设置
    Eclipse中设置代码缩进为空格缩进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小瓦匠学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值