Incremental code analysis tools based on checkstyle, pmd and jacoco
When using code analysis tools to scan a project, it will output all the problems in each file at once. This makes it difficult to perform an effective check on the codes under development before cleaning up all the existing problems.
In response to this pain point, I extended those tools including checkstyle, PMD and jacoco to perform scanning only on incremental changes of code lines.
# Download the install.sh
curl https://raw.githubusercontent.com/yangziwen/diff-check/master/hooks/install.sh > install.sh
# Install the hook to a specified git repository
sh install.sh --repo-path=${the_absolute_path_of_your_git_repository}
# Or install the hook globally
sh install.sh --global=true
# Enable the check of checkstyle
git config diff-check.checkstyle.enabled true
# Disable the check of checkstyle
git config diff-check.checkstyle.enabled false
# Enable the check of PMD
git config diff-check.pmd.enabled true
# Disable the check of PMD
git config diff-check.pmd.enabled false
git config diff-check.checkstyle.config-file /custom_checks.xml
git config diff-check.pmd.rulesets rulesets/java/ali-all.xml
git config diff-check.checkstyle.exclude-regexp .+-client/.*
git config diff-check.pmd.exclude-regexp .+-client/.*
# Specify the message language of both checkstyle and pmd
git config diff-check.language en
# Only specify the message language of checkstyle
git config diff-check.checkstyle.language es
# Only specify the message language of pmd
git config diff-check.pmd.language zh
git config
commands effective globally by add --global
option. <plugin>
<groupId>io.github.yangziwen</groupId>
<artifactId>diff-jacoco-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<excludes>
<!-- Specify the path to exclude -->
<exclude>io/github/yangziwen/quickdao/example/entity/*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- config the path of the report -->
<outputDirectory>${project.reporting.outputDirectory}/jacoco-diff</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
# Incremental code coverage scanning is achieved by specifying commit or branch for `jacoco.diff.oldrev` and `jacoco.diff.newrev`
# If these two parameters are not specified, a full coverage scan will be performed
mvn test -Djacoco.diff.oldrev=9ac9182 -Djacoco.diff.newrev=HEAD
# Use `jacoco.diff.against` parameter,you can compare the difference between HEAD and any other commit or branch, and get the code coverage result between them.
mvn test -Djacoco.diff.against=origin/master
# Use the `jacoco.author.name` or `jacoco.author.email` parameters to complete the coverage scanning according to the incremental code of the specified submitter
mvn test -Djacoco.diff.against=origin/master -Djacoco.author.name=yangziwen
# You can run a single test class and get the report of it
mvn clean test -Djacoco.diff.against=origin/master -DskipTests=false -Dtest=io.github.yangziwen.quickdao.example.repository.UserSpringJdbcRepositoryTest -DfailIfNoTests=false
Full Code Coverage | Incremental Code Coverage |
---|---|
pipeline {
agent any
tools {
maven 'mvn-3.9.4'
}
stages {
stage('Checkout') {
steps {
git branch: 'diff-check-test-branch', url: 'https://github.com/yangziwen/quick-dao'
}
}
stage('Check Style') {
steps {
script {
sh "curl -L -o diff-checkstyle.jar https://github.com/yangziwen/diff-check/releases/download/0.0.8/diff-checkstyle.jar"
def returnStatus = sh returnStatus:true, script: "java -jar ./diff-checkstyle.jar -c /custom_checks.xml ${WORKSPACE} --git-dir ${WORKSPACE} --base-rev=origin/master -f xml -o ${WORKSPACE}/checkstyle-result.xml"
recordIssues tools: [checkStyle(name: 'Diff-CheckStyle', pattern: '**/checkstyle-result.xml', reportEncoding: 'UTF-8')]
if (returnStatus != 0) {
error("Diff-CheckStyle ends with errors")
}
}
}
}
stage('Build and Test') {
steps {
sh 'mvn clean test -Djacoco.diff.against=origin/master'
}
}
stage('Analyze Coverage') {
steps {
recordCoverage(tools: [[parser: 'JACOCO']],
id: 'diff-check-jacoco', name: 'Diff-Check Jacoco Coverage',
sourceCodeRetention: 'EVERY_BUILD',
qualityGates: [
[threshold: 70.0, metric: 'LINE', baseline: 'PROJECT', unstable: true],
[threshold: 70.0, metric: 'BRANCH', baseline: 'PROJECT', unstable: true]])
}
}
}
}
lombok.config
file to the root folder of your project, and add a line of lombok.addLombokGeneratedAnnotation = true
in the file, then all the methods generated by lombok will be ignored in the code coverage scanning(https://projectlombok.org/features/configuration).