SonarQube

本文介绍 SonarQube,StyleCI 和版本控制工具提交规范

SonarQube

SonarQube 是一个代码自动审查工具,用于检测代码中的错误,漏洞和代码异味。它可以与现有的工作流程集成,以便在项目分支和拉取请求之间进行连续的代码检查。官方提供了2种方式,一种是下载后本地搭建,另一种是在线运行。

在线运行

进入SonarCloud,使用 GitHub 账号登录导入我已有的项目

Create Organization 创建组织后,可以开始 Analyze projects 分析你的项目了。这里由于是测试项目,我选择 Free plan,上传后所有人都可以看到源码与分析结果。

开始分析后,SonarCloud 会创建一个 Token,在分析时填写

创建完后,下面要选择项目主要使用的语言,使用的操作系统,还需要下载一个SonarQube Scanner

以 Windows 为例,下载解压后将其中的 /bin 目录加入环境变量,进入你的项目根目录执行如下命令(也可以复制页面自动生成的命令):

D:\WWW\Sm>sonar-scanner.bat 
-D"sonar.projectKey={你的Project Key}" 
-D"sonar.organization={你的Organization Key}" 
-D"sonar.sources=." 
-D"sonar.host.url=https://sonarcloud.io" 
-D"sonar.login={你的Token}"

分析结果如下:

质量分析结果

本地搭建

为了在公司内网使用,我们在服务器自己搭建了这个分析工具,加入了 CI 流程中

拉镜像:

docker pull postgres
docker pull sonarqube

启动

#启动数据库
docker run --name db -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -d postgres
#启动sonarqube
docker run --name sq --link db -e SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar -p 9000:9000 -d sonarqube

PHP规则

把我们一个历史悠久的项目加入检查后,出来了 228 个 Bugs、64 个漏洞、1.5K 安全热点、30K 的异味……

重构之路任重而道远,我们先解决掉 Bugs 类,经过整理后大致分为如下几点:

  1. Remove this unreachable code.
    删除 return 语句后的无用代码

  2. Remove or refactor this statement.
    例如 $i == 0;,需要检查语句正确性或删除掉未使用的语句

  3. This branch duplicates the one on line xxx.
    条件语句的分支条件出现重复,例如:

if ($a > 10) {

} elseif ($a > 5) {

} elseif ($a > 5) {

}
  1. Review the data-flow - use of uninitialized value.
    使用了未初始化的值/数组/对象,例如字符串的 .=,数字的 $i++,数组的 $foo['bar']

  2. Remove this conditional structure or edit its code blocks so that they’re not all the same.
    2个分支语句的内容一样,例如:

if (true) {
    $a = 1;
} else {
    $a = 1;
}
  1. Remove or correct this useless self-assignment.
    等号左右一样,也就是自己等于自己,无用代码

  2. Was “-=”/“!=” meant instead?
    等号后面无空格,和后面的运算符易产生误解

  3. Identical sub-expressions on both sides of operator “&&”/“||”
    与、或运算符左右一样,无意义

  4. “$i” is incremented and will never reach “stop condition”.
    类似 while (true) 的写法,想在循环内部 break,应直接省略条件部分,例如

for ($i = 0; ;$i++)
  1. Remove this “if” statement.
    删除无用的 if (true)

完整的规则可以在 /coding_rules?language=php&types=BUG 中查看

StyleCI

如果是基于 PHP 的开源项目,可以使用 StyleCI 工具

它可以导入 GitHub 账号里的项目,识别每一次提交内容的样式,把不符合规范的代码标红,而且设置后可以拒绝掉不规范的 PR

最方便的是,它会直接给你添加一个修复这些问题的 PR,你只需要看看然后合并就完事了嗷

StyleCI

版本控制工具提交规范

在日常工作中,我们经常会使用版本控制工具,不管是 Git 还是 SVN,或是其它。

在多人协作中,提交注释是一个可能会忽视的点。清晰明了的注释可以降低沟通成本,提高工作效率。而含糊不清的注释会在你需要找一次具体提交时造成麻烦。

规范内容

最基础的规范,也是最重要的——就是每个任务的代码分开提交。这样在 Review 的时候比较清楚,出现 BUG 后可以快速回退单次提交。如果代码管理水平不足,出现了几个环境代码不统一,需要手动合并代码时,可能这个任务需要发布正式,另一个任务只需要发布测试或者预发布,糅杂在一起的提交就会导致噩梦般的后果。

团队合作中一般会使用到事务跟踪工具,例如 JIRA禅道 等。每个开发任务有自己的编号,在提交时一定要带上。

其它规范因人而异,举个例子:

先把文件按类型分为如下几种

  • 【视图】如 Blade、Smarty、PHTML 等
  • 【功能】一般是业务代码,根据项目结构不同可分为 Model、Bean、Business 等
  • 【脚本】定时脚本 Crontab 类,也叫 Job
  • 【测试】单元测试,也叫 Test
  • 【插件】有的框架如 Yaf、Yii 中存在的概念,或者是自己封装的工具类
  • 【配置】根据项目要求的不同,有 php,ini,env,XML,Json 等
  • 【前端】JS、CSS、image等,或者是组件
  • 【接口】提供给外部的接口
  • 【API】调用的外部接口,可进一步分为公司内部的和外网的
  • 【SQL】也叫做 Migration。数据库迁移文件,或是结构变更的纯 SQL
  • 【FUNC】也叫做 helper,全局函数文件

最后拼装成一整条 commit message

【任务编号】【新增|修改|删除】【功能|视图|脚本|等】任务标题-功能备注

如果是复制的代码,可在后面加上 @copy(如果有统计代码量的要求)。再提一嘴,部分要找历史提交的原因可能是因为需求有变更,要还原回之前的代码。刚好脉脉给我推送了一条通知——删除代码时是注释掉还是直接删除。我的选择毫无疑问是直接删除掉,因为有版本控制工具在,找历史还是没啥难度的。如果是仅注释掉的话,代码的美观性可想而知(代码洁癖实锤)。