代码上库前的自动review实现

perlcritic是一款PERL的静态代码检测工具,官网为:http://www.perlcritic.org
源码下载:https://github.com/Perl-Critic/Perl-Critic,可以参考http://search.cpan.org/dist/Perl-Critic/使用,可以使用CPAN安装:

本日志自动扫描工具建立在Critic基础上,为我们的日志检测规则写了一插件,名为RequireLogStatment,安装文件覆盖/usr/local/share/perl/5.14.2/Perl/Critic/Policy/CodeLayout/RequireLogStatment.pm 即可使用。

检测规则

针对部门使用大量PERL代码做日志规范,当前主要检查该打日志的地方未打日志的行为,该打日志的检查点为:
EXITWORD:return, exit, _exit, die

打日志的函数为:
LOGWORD:ldie lemerg lalert lcrit lerror lwarn lnotice linfo ldebug dbg1 dbg2 dbg3 dbgv

不是所有EXITWORD前都要打日志,且日志级别不一定是lerror,例如一个函数运行最后一条return语句作为合法出口不要求打日志,为了避免日志过多,建议大家按照“先处理错误,最后处理正确原则”书写代码,例如:

如果某些语句真不需要日志,可以添加annotation,规则是在语句前一条注释处加:


例如:

日志检测插件与效果

perlcritic使用PERL编写,分析其原理,然后实现如下代码:

目前可检测如下语法unit.pm:

此工具可单独使用:perlcritic -s CodeLayout::RequireLogStatment ./unit.pm

也可配合其他检测选项使用:perlcritic -4 --verbose 8 ./QemuHugePages.pm

根据reviewID扫描并提交reviewboard

上面命令实现后,想要完成自动化,需要实现根据reviewboard的reviewID自动获取代码进行检测,并将检测结果提交成comments形式给reviewboard,由于这部分使用大量Restful API请求,使用js处理request和JSON非常方便,但是node.js最大的问题是默认异步,导致代码并不是很优雅:

此rbjob工具支持如下参数:

# ./rbjob --help

Usage: rbjob [options] [command]

Commands:

retrive [env] Retrive all original/patched files special by reviewid
delcomment [env] Delete all comments submited by this tool

Review Board manage tool

Options:

-h, --help output usage information
-V, --version output the version number
-s, --rserver Review Board server address, default is [127.0.0.1]
-u, --ruser Review Board server login username, default is [root]
-p, --rpass Review Board server login password, default is []
--flog log to file
-r, --reviewID @retrive Review ID
--check @retrive check command, can be "log" "l4" "all" "$userdef", default is [log]
--session [dir] @retrive session record dir, default no session and session dir is [/etc/rb]

rbjob运行效果:

剥去日志,输出类似:

@/src/app/vtp-common/MutexVMs.pm 0 errors
@/src/app/vtp-common/StartOrder.pm 1 errors
@/src/app/vtp-qemu-server/VTP/QemuHugePages.pm 9 errors
@/Test.pm 80 errors need check

检测到错误会打印xx errors,如果是xx errors need check表示检测到错误且是一个新增文件或者改动超过80%的文件,之所以如此,是因为遗留代码不宜强制程序员修改,而新增代码强制要求符合规则比较容易推动。

上述具体的错误信息自动提交到reviewboard上,comments列表效果如:

具体错误信息如:

以上错误信息还会发送到内部邮件:

自动扫描

rbjob实现了根据reviewID自动下载代码,然后运行工具检测告警,然后将告警自动提交成review comments,但是需要人工来调用rbjob才能执行,如何做到自动在后台监控?
找了一下reviewboard没有提供最进改动review列表API,但是从页面上看有此功能,于是用curl定时将最近改动列表抓下来,然后自动调用rbjob,此脚本取名rbeye:

运行rbeye,由于rbjob我们还会在cgi里面调用,cgi owner是www-data,www-data读写文件权限受限较多,需要特别注意不同用户操作导致权限不够情况。SSH链接进程会在SSH CLIENT退出时候SIG HUB给子进程,需要考虑,例如:

nohup command ...
screen -dmS newscreen; screen -list; screen -r newscreen; command ...

SVN PRE-COMMIT

为了在SVN上库流程卡主代码,需要对svn提交做HOOK,将svn pre-commit通过网络请求转发到自动检测代码,这段流程已经有,在已有的reviewboard HOOK脚本处添加检测调用:

这里检测是否有错是检测输出里面是否有"errors need check",且检测标准和rbeye里面的有所不同,这里检测的是log,rbeye里面检测的是l4,如前面所述,只对判定为新增文件的PERL代码做强制要求,不符合规定就无法上库,所以,这里控制了报错,只要求新增代码做日志规范。阻止上库效果:

此时,你需要打开reviewboard查看并处理相应的错误,然后重新提交改动后的代码到同一review,如果没有错误了,下次提交会顺利通过。

PDF下载
OReilly.Perl.Best.Practices.chm
rbeye
rbjob
RequireLogStatment.pm
unit.pm

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">