Checkstyle on Changed Files with Gradle

Running quality checks on modified files in pull requests

--

About a month ago, the Android team at mobile.de introduced a new process to review Pull Requests. We now run Checkstyle before merging to ensure the changes meet our coding standards.

Executed Checks of a Pull Request

Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard. It automates the process of checking Java code to spare humans of this boring (but important) task.

checkstyle.sourceforge.net

Adding the Default Checkstyle Task to a Project

Checkstyle can be easily integrated in Gradle-based (Android) projects by applying the plugin and configuring it in the build script:

See the Gradle docs for more information on the configuration options.

To run the quality checks on your project’s Java source files, run the checkstyle Gradle task:

./gradlew checkstyle

With the settings above, Checkstyle prints any issues it finds to the console, and generates XML and HTML reports. The XML report is especially useful if you want to parse the results from Jenkins and create a health report.

Checking Changes with a New Gradle Task

When we first executed the task, Checkstyle reported more than 30.000 issues. There’s no way we could fix that many issues in a single run, so we decided to do it incrementally and just check the modified files in each pull request.

We used the GitHub pull request builder plugin to run the task on our Jenkins server and report the result back to GitHub. Unfortunately, the default Gradle checkstyle task runs on every file in the project.

We needed a way to run the checks on the changed files, but ignore the rest. With Git, it’s relatively easy to get a list of all modified (but not renamed or deleted) files with this command:

The GitHub pull request builder provides a nice set of environment variables with every build:

  • ghprbActualCommit
  • ghprbActualCommitAuthor
  • ghprbActualCommitAuthorEmail
  • ghprbPullDescription
  • ghprbPullId
  • ghprbPullLink
  • ghprbPullTitle
  • ghprbSourceBranch
  • ghprbTargetBranch
  • sha1

The parameters for the source and target branch are particularly useful here. Since some branches may not be locally available on your Jenkins server, you might need to prefix them with origin/.

The acquired information needs to be parsed and passed to Checkstyle. We created a new Gradle task calledcheckstyleChanged that extends the normal Gradle task checkstyle task with additional options:

This moves the task-specific configuration so it applies to all Checkstyle tasks.

Setting Custom Parameters and Determining Parent Branches

We modified our method so we can pass the target branch to the Gradle task as a parameter -Pbranch=<branch> instead of providing it through an environment variable:

You can use the following function to let Gradle determine the parent branch automatically:

To use this approach in your own projects, get the Gist with the full source code of our codestyle.gradle and include it in your project by adding apply from: “checkstyle.gradle” to your main build file.

--

--

Marc Prengemann
Berlin Tech Blog (by Kleinanzeigen and mobile.de)

Software Engineer @Google, previously Android Developer @zalandotech, @SoundCloud, @mobile_de, @Wire, intern @Facebook