背景

试想一下,团队每个人的代码风格千奇百怪,代码质量参差不齐,作为团队的管理者是不是会很头疼?如果有一个代码审查机制,让所有人遵循共同的规范,并且能起到监管的作用,这个审查标准还可以不断扩展优化,岂不爽哉?

经过多方研究,目前的代码扫描方法各有优劣。

1、SonarQube,目前主流的代码质量扫描平台。优势是支持插件扩展,功能强大;支持在线报告查看和审批;支持筛选规则;很多大厂比如阿里云效都有使用,上车不用担心翻车。缺点是无法在线扩展规则;大多数规则都是英文不太友好。

2、alibaba/p3c,也就是很多人熟知的阿里代码编写规范,本质上是利用PMD编写的代码风格扫描IDE插件。优点是全中文容易理解,规则扩展相对较容易(实际上这点有待确认,因为无论sonarqube还是pmd扩展规则都需要开发代码);缺点是BUG扫描能力较弱,只能给出编码规范的建议;而且这个项目的规则相对较少只有五十几条,扫描能力不够强大。

 经过一番考量,笔者认为应该将两者结合起来,p3c的规则用来规范代码风格,sonarQube的规则用来提高代码质量,两全其美。

SonarQube

首先要做的就是SonarQube的搭建。其实很简单,经过我一番摸索,只需要两行命令就可以搞定。

docker run -d --name postgres -e POSTGRES_PASSWORD=csf@123 \
    -e ALLOW_IP_RANGE=0.0.0.0/0 -v pgdata:/var/lib/postgresql/data \
    -p 55432:5432 postgres:13-alpine3.16

上面的代码是启动一个postgres数据库,开放55432端口是为了使用一些桌面应用方便管理,实际上不是必须。    

docker run -d --name sonarqube \
    -p 9000:9000 \
    --link postgres \
    -e SONAR_JDBC_URL="jdbc:postgresql://postgres:5432/postgres?currentSchema=public" \
    -e SONAR_JDBC_USERNAME=postgres \
    -e SONAR_JDBC_PASSWORD=csf@123 \
    -v sonarqube_data:/opt/sonarqube/data \
    -v sonarqube_extensions:/opt/sonarqube/extensions \
    -v sonarqube_logs:/opt/sonarqube/logs \
    sonarqube:8.9.9-community

上面的代码是启动sonarqube服务器,通过--link的方式与postgres数据库交互,因此是走的内部端口5432而不是55432。

现在正常情况下就可以访问ip:9000进行sonarqube页面访问了,如下图所示。默认账户是admin/admin

sonarQube java代码规则下载 sonarqube自定义规则开发_规则集

 但是真正要实现上面的效果,还有几件事情要做。

SonarQube汉化

这一步是可选项,不需要的可以跳过。首先你得确保SonarQube能够正常连接外网,然后打开Settings->marketplace,搜索Chinese Pack,点击安装。然后点击Restart Server重启服务,一切就OK了。但如果你的SonarQube是离线环境下,就会比较复杂一些。

离线环境的安装plugin的关键是获取到这个plugin对应的Jar包。因此可以在一个有网络的环境临时搭建一个SonarQube,然后按照上面的步骤将plugin先装上。

其次,在Linux服务器上查找sonarqube_extensions卷对应的挂载目录。

docker volume inspect sonarqube_extensions

#上面的命令会产生类似下面的结果,其中Mountpoint就是挂载目录
[
    {
        "CreatedAt": "2022-08-02T20:22:07+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/sonarqube_extensions/_data",
        "Name": "sonarqube_extensions",
        "Options": null,
        "Scope": "local"
    }
]

然后得到/var/lib/docker/volumes/sonarqube_extensions/_data/plugins下的jar包,将其拷贝到离线环境中sonarqube_extensions卷下的plugins目录中,再Restart Server就可以了。

与本地项目联动

第一步,先打开ip:9000/account/security,在SonarQube中创建一个token。

sonarQube java代码规则下载 sonarqube自定义规则开发_规则集_02

 第二步,点击“质量配置”创建自己的规则集合。这是因为默认的Sonar Way对应的规则不允许禁用。

sonarQube java代码规则下载 sonarqube自定义规则开发_规则集_03

 创建好规则集合后,可以选择激活自己想要的规则。这里其实可以发现Sonar Way中的规则是全集,自定义的规则集合只能是子集。这一点对于后面的规则扩展而言是一个小小的挑战。

sonarQube java代码规则下载 sonarqube自定义规则开发_离线_04

 上面的页面是点击未激活规则数进来的,在这里可以批量激活和挂起规则,也可以点击某条规则单独激活和挂起。

当我们的规则集合(app)创建好之后,就可以将规则与项目关联起来了。

第三步,点击项目,新增一个项目。在token那里填写之前申请的token值,也可以创建新的token。完成之后会提示如何与本地项目进行集成,并会告诉你执行扫描的命令。如果项目中主要是JS/TS/Go等构建技术,需要在本地下载一个SonarScanner。这里就不展开了。

在执行扫描之前,我们需要将上一步创建的规则集合应用起来,否则会使用默认的Sonar Way。点击右上角的项目配置,点击质量配置,进入配置页面。

sonarQube java代码规则下载 sonarqube自定义规则开发_代码规范_05

 点击添加语言,选择我们创建的规则集合app,点击保存。

sonarQube java代码规则下载 sonarqube自定义规则开发_离线_06

 现在可以在本地执行上面提示给出的扫描命令,执行完成后就可以在SonarQube中看到结果。

与SonarLint联动

虽然上面的效果能够让我们每次都可以对代码进行扫描,可以在web页面中看到报告,但来回切换始终不太方面。笔者希望能在本地就通过统一的规则进行扫描,修改后在提交代码时、或者在持续集成流程中再触发web报告生成和阈值判定,这样能提高修改代码的爽度。因此这里不得不提到SonarLint这个IDE插件。

经过实际验证,VSCode和IDEA两款常用IDE工具都支持SonarLint插件,安装插件的过程非常简单,这里主要讲一下配置过程。

IDEA中打开Settings,搜索SonarLint,点击SonarQube connections下的新增按钮,填写前面的token就可以完成连接。接下来就是如何与SonarQube联动的部分了。

sonarQube java代码规则下载 sonarqube自定义规则开发_离线_07

展开SonarLint配置,点击Project Settings,将本地项目与SonarQube中的ProjectKey进行绑定。

sonarQube java代码规则下载 sonarqube自定义规则开发_代码规范_08

绑定完成后,如果这时候执行扫描,会发现规则与SonarQube中定义的不一致。这个地方是一个小坑。这是因为绑定后插件并不会自动实现规则同步,而是需要手动点击Update binding才能同步。这个按钮在哪儿呢?在SonarLint配置中,也就是上上张图片里面。

以后每次SonarQube的规则变化,都最好手动点击一下Update binding。

上面的步骤完成后,我们就可以用远程规则在本地进行扫描,及时修改代码。

PMD和P3C