概述
又搞一邊質量掃描插件,之前做過一遍,然后后面各種忽略,然后就放棄了,所以,應該尋找一種方法,循序漸進的實施。本次將實施一個基本的打包掃描方案,包含
- checkstyle 固定團隊編碼風格,固定命名風格以及換行風格等,原型配置出資googlestyle, 修改縮進為4個字符(原型是2個)
- surefile test report Junit Test結果報告
- JaCoCo test coverage 代碼測試覆蓋率插件
- 阿里巴巴Java代碼掃描插件P3C(PMD)
- cpd 重復代碼掃描
- Findbugs 通用Java bug檢查
- Sonar Quabe 一站式代碼質量審查平台
1. Maven pom插件安裝
現有完整的代碼demo: https://github.com/Ryan-Miao/code-quality-verify-demo
具體插件內容,查看 https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/pom.xml
這里大概敘述下配置原理。首先,maven構建生態分build和report,而build又分verify, compile, test, install等生命周期。我們的插件就是基於這幾個概念而產生作用的。
先說report插件,位於reporting目錄下,主要是在執行mvn site的時候生成各種html report,這里綁定了想要生成各種report的的插件配置。生成的report文件最終位於target/site。
然后是build插件,在構建過程中發生作用。這里可以綁定插件執行到構建過程,比如verify, 當執行install的時候,我們插件就會執行。考慮為了查看report,這里就不綁定生命周期,而是直接通過執行goal的方式來檢查。
需要注意的是:
1.Jacoco的覆蓋率,目前只配置了全局行覆蓋和分支覆蓋,不添加閾值則為0,修改閾值實現覆蓋率的控制。可以過濾不需要掃描的文件,比如生成的java文件。
2.checkstyle,這個讀取我們自定義的checkstyle的配置,后期在使用過程中修改完善程我們自己的配置方案。可以過濾不需要掃描的文件,比如生成的java文件。
3.阿里巴巴Java規范,這個是PMD掃描,但移除了PMD自帶的n條規則,只執行阿里的規則,可以過濾不需要掃描的文件,比如生成的java文件。
4.findbugs,指定了配置文件,里面可以配置忽略的文件和bug類型。當然,也可全局配置。
在代碼里通過注解或者注釋忽略掃描:
1.1 checkstyle忽略
忽略單獨的代碼模塊,比如spring security的配置
//CHECKSTYLE:OFF
public void someMethod(String arg1, String arg2, String arg3, String arg4) {
//CHECKSTYLE:ON
忽略匹配正則
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<configLocation>config/checkstyle/google-checks-6.18.xml</configLocation>
<consoleOutput>true</consoleOutput>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<skip>false</skip>
<failsOnError>false</failsOnError>
<linkXRef>true</linkXRef>
<violationSeverity>error</violationSeverity>
<!--<includes>**/TestController.java</includes>-->
<excludes>**/generated/**.java</excludes>
<excludes>**/**Vo.java</excludes>
</configuration>
</plugin>
1.2 P3C阿里Java掃描PMD忽略
阿里Java掃描插件使用的PMD來實現,對於某些類不想執行掃描,可以在類上添加注解
@SuppressWarnings("PMD")
也可以直接在excludes里配置
<excludes>
<exclude>**/*Bean.java</exclude>
<exclude>**/generated/**.java</exclude>
</excludes>
1.3 FindBugs掃描忽略
FindBugs有些檢查我們不想改,比如總是判定Date類是可變的。事實上,我們應該都切換為LocalDate或LocalDateTime,但總有遺留代碼采用Date,此時可以忽略掃描
修改配置文件https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/config/findbugs/findbugs-exclude.xml,
比如正則匹配
<Match>
<Class name="~.*\.entity\..*" />
</Match>
<Match>
<Class name="~.*\.vo\..*" />
</Match>
還可以:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
然后:
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
value = {"MT_CORRECTNESS", "STYLE"},
justification = "I know what I'm doing")
public JdbcTemplate get(String datasourceName) {
JdbcTemplate jdbcTemplate = TEMPLATE.get(datasourceName);
if (jdbcTemplate == null) {
synchronized (this) {
if (jdbcTemplate == null) {
jdbcTemplate = createTemplate(datasourceName);
TEMPLATE.put(datasourceName, jdbcTemplate);
}
return jdbcTemplate;
}
}
return jdbcTemplate;
}
2 生成report
上面的pom配置后,執行mvn install site
即可生成各種報告
阿里Java檢查報告:
checkstyle編碼規范報告:
有時候你會發現會爆出這個問題Skipping JaCoCo execution due to missing execution data file,大多數原因是因為沒有編譯測試類
3 檢查閾值
site命令會生成對應的report,但實際開發中,我們會期望出現錯誤時停止構建,提醒開發者修復問題。bug發現的越早,修復的成本越低。那么,就需要給各個掃描插件設定失敗閾值。
3.1Checkstyle設定失敗
我們可以選擇把checkstyle:check綁定到verify的生命周期上,這樣工程師每次變異都會掃描,當出現不符合規范的code style就會編譯失敗。也可以在檢查的時候手動執行一下check。最終,我選擇了手動check方案。
mvn checkstyle:check
3.2 阿里巴巴Java掃描設定失敗
mvn pmd:check
3.3 Findbugs 發現bug失敗
findbugs:check
4 Jenkins集成
代碼質量不能靠個人素質來維護,而是通過完善的流程制度來保障。我們的代碼開發最終都要merge到開發分支。我們只要卡住合並時的代碼質量就可以了。規定:當代碼合並到dev或者master等保護分支時,CI構建必須success,否則不允許合並分支。
集成Jenkins和Gitlab,添加Merge-Request/Pull-Request掃描任務,當發起Pull Request后自動Jenkins構建,並將構建結果寫回Gitlab。
我們使用Jenkins pipeline來配置任務,編寫Jenkinsfile
https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/Jenkinsfile
當任務構建時,我們會生成報告,然后,檢查是否通過了掃描。
我們使用Jenkins Warnings Next Generation插件
該插件也提供了qualityGates來根據掃描結果中斷構建,但為了保證配置一致性,我采用maven插件自帶構建失敗功能。當所有掃描通過了即構建成功,允許合並。