We can fail the build when unwanted packages (e.g., junit.framework
) are imported through Gradle’s built-in checkstyle plugin. Setup is different for solo-project and multi-project builds. See the following links for a git diff of what is needed to enable this behavior:
Context
I never want to bring in anything from the junit.framework
package when writing new code. Gradle’s checkstyle plugin and the IllegalImport rule can help me formalize this intention as part of my build.
The build file is the best place to capture intentions like this because it is shared by everyone who touches the project. While it is possible to configure IDEs to exclude unwanted packages from import, the default behavior is that terrible choice above - where most of the options are wrong.
Solo-Project Setup
We’ll start with a simple example project that has imported a method from our unwanted package: sghill/fail-unwanted-package-imports.
Apply the plugin:
apply plugin: 'checkstyle'
The plugin is looking for configuration in ${project.projectDir}/config/checkstyle/checkstyle.xml
by default.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="TreeWalker">
<module name="IllegalImport">
<property name="illegalPkgs" value="junit.framework"/>
</module>
</module>
</module>
Now running ./gradlew build
fails our new :checkstyleTest
task:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':checkstyleTest'.
> Checkstyle rule violations were found. See the report at: file:///Users/sghill/code/build-well/fail-unwanted-package-imports/build/reports/checkstyle/test.html
Multi-Project Setup
We’re going to reuse the solo-project configuration in the same location for our multi-project setup. The default checkstyle file path is relative to the project
instead of the rootProject
, so we’ll need to do some task configuration. This is the way to share a checkstyle configuration:
allprojects {
apply plugin: 'checkstyle'
tasks.withType(Checkstyle) {
def path = "${rootProject.projectDir}/config/checkstyle/checkstyle.xml"
config resources.text.fromFile(path)
}
}
Now running ./gradlew build --continue
gives us errors from foundation
and acceptance
:
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':acceptance:checkstyleTest'.
> Checkstyle rule violations were found. See the report at: file:///Users/sghill/code/build-well/fail-unwanted-package-imports/acceptance/build/reports/checkstyle/test.html
==============================================================================
2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':foundation:checkstyleTest'.
> Checkstyle rule violations were found. See the report at: file:///Users/sghill/code/build-well/fail-unwanted-package-imports/foundation/build/reports/checkstyle/test.html
Reports
By default reports are produced in xml and html formats:
${project.buildDir}/reports/checkstyle/*.xml
${project.buildDir}/reports/checkstyle/*.html
Versions
This example has been tested against the following versions:
Date | Gradle | Checkstyle | Solo-Project | Multi-Project |
---|---|---|---|---|
2017-06-20 | 4.0 | 6.19 | output | output |
2017-06-20 | 3.5.1 | 6.19 | output | output |
2017-06-20 | 3.4.1 | 5.9 | output | output |
2017-06-20 | 3.3 | 5.9 | output | output |