背景
试想一下,团队每个人的代码风格千奇百怪,代码质量参差不齐,作为团队的管理者是不是会很头疼?如果有一个代码审查机制,让所有人遵循共同的规范,并且能起到监管的作用,这个审查标准还可以不断扩展优化,岂不爽哉?
经过多方研究,目前的代码扫描方法各有优劣。
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汉化
这一步是可选项,不需要的可以跳过。首先你得确保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。
第二步,点击“质量配置”创建自己的规则集合。这是因为默认的Sonar Way对应的规则不允许禁用。
创建好规则集合后,可以选择激活自己想要的规则。这里其实可以发现Sonar Way中的规则是全集,自定义的规则集合只能是子集。这一点对于后面的规则扩展而言是一个小小的挑战。
上面的页面是点击未激活规则数进来的,在这里可以批量激活和挂起规则,也可以点击某条规则单独激活和挂起。
当我们的规则集合(app)创建好之后,就可以将规则与项目关联起来了。
第三步,点击项目,新增一个项目。在token那里填写之前申请的token值,也可以创建新的token。完成之后会提示如何与本地项目进行集成,并会告诉你执行扫描的命令。如果项目中主要是JS/TS/Go等构建技术,需要在本地下载一个SonarScanner。这里就不展开了。
在执行扫描之前,我们需要将上一步创建的规则集合应用起来,否则会使用默认的Sonar Way。点击右上角的项目配置,点击质量配置,进入配置页面。
点击添加语言,选择我们创建的规则集合app,点击保存。
现在可以在本地执行上面提示给出的扫描命令,执行完成后就可以在SonarQube中看到结果。
与SonarLint联动
虽然上面的效果能够让我们每次都可以对代码进行扫描,可以在web页面中看到报告,但来回切换始终不太方面。笔者希望能在本地就通过统一的规则进行扫描,修改后在提交代码时、或者在持续集成流程中再触发web报告生成和阈值判定,这样能提高修改代码的爽度。因此这里不得不提到SonarLint这个IDE插件。
经过实际验证,VSCode和IDEA两款常用IDE工具都支持SonarLint插件,安装插件的过程非常简单,这里主要讲一下配置过程。
IDEA中打开Settings,搜索SonarLint,点击SonarQube connections下的新增按钮,填写前面的token就可以完成连接。接下来就是如何与SonarQube联动的部分了。
展开SonarLint配置,点击Project Settings,将本地项目与SonarQube中的ProjectKey进行绑定。
绑定完成后,如果这时候执行扫描,会发现规则与SonarQube中定义的不一致。这个地方是一个小坑。这是因为绑定后插件并不会自动实现规则同步,而是需要手动点击Update binding才能同步。这个按钮在哪儿呢?在SonarLint配置中,也就是上上张图片里面。
以后每次SonarQube的规则变化,都最好手动点击一下Update binding。
上面的步骤完成后,我们就可以用远程规则在本地进行扫描,及时修改代码。