本文来自:
杨周 极狐GitLab 高级解决方案架构师
代码越写越规范是优秀开发者的成长之路,但很多人对老项目感到有心无力,因为太不规范了,所有人停下来一起修复也要花费很长时间,而且一次改动太多难以确保可靠性,怎么办?
有的语言可以借助 Git diff 把本次修改的代码挑出来,实现增量扫描,但 Java 很难这么做。
有的人在持续集成里配置了规范扫描工具,但报错之后需要在成千上万行 log 里查找,降低了研发效率。
Checkstyle 是业界知名的开源扫描工具,可扫描 Sun、Google 等代码规范,提供Maven、Gradle 插件。本文以 Java 项目配置 Checkstyle 扫描工具为例,分享消灭这些问题的办法:
1. 将代码规范问题显示在「合并请求页面」,大幅度提高研发效率;
2. 增量代码规范报告。
下文分别介绍「Java Maven 项目」和「Java Gradle 项目」的配置方法。
在项目中引入 Checkstyle 插件,并下载代码规范:
$ vi pom.xml
org.apache.maven.plugins maven-checkstyle-plugin 3.2.0 UTF-8 true true warning config/checkstyle/checkstyle.xml
$ mkdir -p config/checkstyle/
$ wget https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-9.3/src/main/resources/google_checks.xml -O config/checkstyle/checkstyle.xml
执行全量扫描命令,查看效果:
$ ./mvnw checkstyle:check[WARN] Demo.java:6:1: 缺少 Javadoc 。 [MissingJavadocType]
[WARN] Demo.java:9:1: 行内含有制表符 tab 。 [FileTabCharacter]
[WARN] Demo.java:9:9: 'method def modifier' 缩进了8个缩进符,应为2个。 [Indentation]
在极狐GitLab 持续集成中执行强制扫描:
$ vi .gitlab-ci.ymlcheckstyle:script:- ./mvnw checkstyle:check
当扫描工具报错,持续集成退出,想看代码规范问题,需要到 log 中查找。很多持续集成产品只做到了这一步,但这降低了开发效率,因此极狐GitLab 更进一步——采集「代码质量报告」。
在项目中引入 violations-maven-plugin,它会将 Checkstyle 报告转换成极狐GitLab 标准格式。
$ vi pom.xml
se.bjurr.violations violations-maven-plugin 1.50.4 validate violations 0 0 0 0 30 gl-code-quality-report.json INFO VERBOSE 99999999 true INFO VERBOSE 99 true . CHECKSTYLE Checkstyle . .*/target/checkstyle-result\.xml$
在极狐GitLab CI 中采集代码规范报告:
image: eclipse-temurin:8cache:paths:- /root/.m2stages:- lint- buildcheckstyle:allow_failure: truestage: lintscript:- ./mvnw checkstyle:checkartifacts:when: alwaysuntracked: truereport:stage: lintscript:- ./mvnw validateneeds:- job: checkstyleartifacts: trueartifacts:reports:codequality: gl-code-quality-report.jsoncompile:stage: buildscript:- ./mvnw package -Dmaven.test.skip=trueartifacts:untracked: true
可以看到在开发人员频繁使用的「合并请求」页面,直接显示了「代码规范问题」,供开发人员自助修复以及提醒评审的同事注意,这样可以有效提高研发效率。
老项目第一次配置代码规范可能会出现很多错误(比如上图有 7746 个),没关系,先将规范合并进入主干,下次修改代码发起合并请求时,极狐GitLab 将展示「增量代码质量报告」,而无需任何复杂设置。比如下图就只有 5 个新问题了:
「Java Gradle 项目」和「Java Maven 项目」的配置方法一致:
在项目中引入 Checkstyle 插件,并下载代码规范:
$ vi build.gradle
plugins {id 'checkstyle'
}
checkstyle {toolVersion = '9.3'maxWarnings = 0maxErrors = 0
}
$ mkdir -p config/checkstyle/
$ wget https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-9.3/src/main/resources/google_checks.xml -O config/checkstyle/checkstyle.xml
执行全量扫描命令,查看效果:
$ ./gradlew check[WARN] Demo.java:6:1: 缺少 Javadoc 。 [MissingJavadocType]
[WARN] Demo.java:9:1: 行内含有制表符 tab 。 [FileTabCharacter]
[WARN] Demo.java:9:9: 'method def modifier' 缩进了8个缩进符,应为2个。 [Indentation]
在极狐GitLab 持续集成中执行强制扫描:
$ vi .gitlab-ci.ymlcheckstyle:script:- ./gradlew check
同样,在项目中引入 violations-maven-plugin,它会将 Checkstyle 报告转换成极狐 GitLab 标准格式。
$ vi build.gradle
buildscript {repositories {maven { url 'https://plugins.gradle.org/m2/' }}dependencies {classpath "se.bjurr.violations:violations-gradle-plugin:1.52.2"}
}task violations(type: se.bjurr.violations.gradle.plugin.ViolationsTask) {//// Optional config//maxReporterColumnWidth = 0 // 0 means "no limit"maxRuleColumnWidth = 60maxSeverityColumnWidth = 0maxLineColumnWidth = 0maxMessageColumnWidth = 50codeClimateFile = file('gl-code-quality-report.json') // Will create a CodeClimate JSON report.violationsFile = file('violations-file.json') // Will create a normalized JSON report.//// Global configuration, remove if you dont want to report violations for// the entire repo.//minSeverity = 'INFO' // INFO, WARN or ERRORdetailLevel = 'VERBOSE' // PER_FILE_COMPACT, COMPACT or VERBOSEmaxViolations = 99999999 // Will fail the build if total number of found violations is higherprintViolations = true // Will print violations found in diff//// Diff configuration, remove if you dont want to report violations for// files changed between specific revisions.//// diff-properties can be supplied with something like://// ./gradlew violations -PdiffFrom=e4de20e -PdiffTo=HEAD//// And in Travis, you could add://// script:// - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./gradlew check -PdiffFrom=$TRAVIS_PULL_REQUEST_BRANCH -PdiffTo=$TRAVIS_BRANCH ; fi'//diffFrom = project.properties.diffFrom // Can be empty (ignored), Git-commit or any Git-referencediffTo = project.properties.diffTo // Same as abovediffMinSeverity = 'INFO' // INFO, WARN or ERRORdiffDetailLevel = 'VERBOSE' // PER_FILE_COMPACT, COMPACT or VERBOSEdiffMaxViolations = 99 // Will fail the build if number of violations, in the diff within from/to, is higherdiffPrintViolations = true // Will print violations found in diffgitRepo = file('.') // Where to look for Git//// This is mandatory regardless of if you want to report violations between// revisions or the entire repo.//// Many more formats available, see: https://github.com/tomasbjerre/violations-libviolations = [["CHECKSTYLE", buildDir.path, ".*/checkstyle/.*\\.xml\$", "Checkstyle"]]
}
在极狐GitLab CI 中采集代码规范报告:
image: eclipse-temurin:8cache:paths:- /root/.m2stages:- lint- buildcheckstyle:allow_failure: truestage: lintscript:- ./gradlew checkartifacts:when: alwaysuntracked: truereport:stage: lintscript:- ./gradlew violationsneeds:- job: checkstyleartifacts: trueartifacts:reports:codequality: gl-code-quality-report.jsoncompile:stage: buildscript:- ./gradlew build -x check -x testartifacts:untracked: true
剩余步骤与「Java Gradle 项目」一致:开发人员频繁使用的「合并请求」页面,直接显示了「代码规范问题」,供开发人员自助修复以及提醒评审的同事注意,有效提高研发效率。
老项目第一次配置代码规范可能会出现很多错误(比如上图有 7746 个),没关系,先将规范合并进入主干,下次修改代码发起合并请求时,极狐GitLab 将展示「增量代码质量报告」,而无需任何复杂设置,比如下图只有 5 个新问题:
这样,我们就通过极狐GitLab 平滑落地了 Java 增量代码规范,让项目代码越来越优雅。