@wxf
2019-04-02T13:59:18.000000Z
字数 5733
阅读 1562
Linux
在项目开发过程中,为了能够使团队成员的代码风格保持一致,我们考虑在SVN服务端搭建一个代码风格校验环境。其作用就是在SVN提交代码时,强制检查代码风格,拒绝那些不符合要求的代码。在搭建环境的过程中遇到了各种各样的问题,走了不少弯路,而且网上关于这方面的资料较少且不全面。经过多次尝试和调试终于搭建成功,现将完整过程记录下来,以供参考。
在这里我们采用的解决方案是:SVN服务端 + svnchecker-0.3 + checkstyle-5.3。其中需要特别注意的是:svnchecker-0.3依赖于Python2,而且它和高版本的checkstyle不兼容。svnchecker项目中存在一些bug需要我们自己修改,后面会介绍。
工作原理:
安装准备:
CentOS release 6.5 (Final)
、Python2.6
、JDK1.8.0_92
(不影响环境搭建)、svn 1.6.11
安装步骤:
配置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=
说明:
[DEFAULT]
:必须配置,svnchecker会根据该标签进行配置信息的读取,若不配置,运行时会提示找不到配置文件Main.PreCommitChecks
:配置为Checkstyle
即可Main.Regex
:不用配置,但必须存在。若配置则报错,原因未知。Checkstyle.FailureHandlers
:配置为Console
即可Checkstyle.Java
:配置为%JAVA_HOME%/bin/java
Checkstyle.Classpath
:checkstyle-5.3-all.jar
文件位置Checkstyle.ConfigFile
:checkstyle.xml
文件的位置Checkstyle.CheckFiles
:配置要检查的文件,内容为正则表达式。格式如:^geeker/geeker-web/.*\.java$|^geeker/geeker-common/.*\.java$
,表达式中geeker
为版本库名,geeker-web
和geeker-common
为该版本库下的两个项目。所以我们可以通过这里的正则表达式来控制SVN服务器对哪个版本库或哪个项目进行风格检查。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文件中进行下面的配置,否则会报错。
# -*- coding:UTF-8 -*-
引入sys
import sys
在run方法中添加如下内容
reload(sys)
sys.setdefaultencoding('utf-8')
校验反馈乱码问题
通过上面的配置,我们的环境基本上算是完成了,但是如果你在checkstyle.xml文件中对校验返回信息进行了中文国际化,那么当你在使用SVN提交文件时遇到风格错误,反馈信息中就会出现中文乱码问题。
具体原因应该是,CheckStyle将风格错误信息输出到svnchecker时产生乱码,所以对于这样的问题就需要我们自己修改两者之间的数据传输方式。我采取的解决方案是在CheckStyle中将风格错误信息转化为Unicode编码,svnchecker接收到以后再将Unicode装换为UTF-8格式的中文。具体修改如下:
com.puppycrawl.tools.checkstyle.DefaultLogger.java
中的public void addError(AuditEvent aEvt)
方法,将该方法中的输出信息转为Unicode编码。修改后将代码打包并替换checkstyle-5.3-all.jar中的对应文件。通过上面的修改可以完美解决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文件的路径地址字符串。因此我们只需将这个字符串进行拆分就可以了。具体修改如下:
修改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 密码: 4zfv
兼容JDK8语法
之前SVN代码风格校验版本不兼容JDK8语法,现重新提供一个新版本的Checkstyle,替换原有版本。
替换方案:
-c G:/checks/geeker_checks.xml E:/WorkSpace/geeker-common/src/main/java/com/geeker/common
修改Checkstyle检验配置文件(xml文件)
① 找到 ParenPad 检验节点,
② 将 tokens 属性的value值改为 CTOR_CALL,METHOD_CALL,SUPER_CTOR_CALL
例如:
<module name="ParenPad">
<property name="severity" value="error"/>
<property name="tokens" value="CTOR_CALL,METHOD_CALL,SUPER_CTOR_CALL"/>
<message key="ws.followed" value="''{0}''后面有空格"/>
<message key="ws.preceded" value="''{0}''前面有空格"/>
</module>
修改svnchecker-0.3的提交检验方法
在svnchecker-0.3安装目录找到checks文件夹下的Checkstyle.py文件。
① 释放41行的注释
② 将42、43、44行注释掉
例如:
相关推荐
为配合SVN服务端的校验检查我们最好在本地开发工具中也配置同样的代码风格检验,从而做到将不符合规范的代码扼杀在摇篮中。
在Eclipse上安装和使用Checkstyle
在IDEA上安装和使用Checkstyle
其他相关设置
Eclipse中设置代码缩进为空格缩进