You can open this sample inside an IDE using the IntelliJ native importer or Eclipse Buildship. |
This sample shows how precompiled script plugins can be used to compose build logic using built-in Gradle plugins, external Gradle plugins and other utility classes.
Use case
As an example, let’s say an organization produces two types of Java software - services and libraries. We want to apply a set of code quality checking rules to both types of projects and configure some aspects specific to each type.
This is achieved by layering three separate plugins:
-
com.example.java-convention
- configures conventions that are generic for any Java project in the organization. -
com.example.library
- adds publishing configuration to publish to the organization’s repository. -
com.example.service
- adds integration tests and checks for mandatory content in a README.
We’ve put the plugins in the plugins
directory in the sample. All plugins created in this sample contain functional tests that use TestKit to verify their behavior.
This root of this sample contains a consumer project that demonstrates how the plugins can be consumed using a composite build:
rootProject.name = 'consumer-service'
includeBuild('plugin')
plugins {
id 'com.example.service' version '1.0'
}
rootProject.name = "consumer-service"
includeBuild("plugin")
plugins {
id("com.example.service") version "1.0"
}
Things to note
Applying an external plugin in precompiled script plugin
The com.example.java-convention
plugin uses SpotBugs plugin to perform static code analysis.
SpotBugs is an external plugin - external plugins need to be added as implementation dependencies before they can be applied in a precompiled script plugin:
repositories {
gradlePluginPortal() // so that external plugins can be resolved in dependencies section
}
dependencies {
implementation 'gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.0.5'
testImplementation 'org.spockframework:spock-core:1.3-groovy-2.5'
}
repositories {
gradlePluginPortal() // so that external plugins can be resolved in dependencies section
}
dependencies {
implementation("gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.0.5")
testImplementation("junit:junit:4.13")
}
-
The dependency artifact coordinates (GAV) for a plugin can be different from the plugin id.
-
The Gradle Plugin Portal (
gradlePluginPortal()
) is added as a repository for plugin dependencies. -
The plugin version is determined from the dependency version. Precompiled script plugins cannot supply a different version for now.
Once the dependency is added, the external plugin can be applied in precompiled script plugin by id:
plugins {
id 'java'
id 'checkstyle'
// NOTE: external plugin version is specified in implementation dependency artifact of the project's build file
id 'com.github.spotbugs'
}
plugins {
java
checkstyle
// NOTE: external plugin version is specified in implementation dependency artifact of the project's build file
id("com.github.spotbugs")
}
Applying other precompiled script plugins
Precompiled script plugins can apply other precompiled script plugins.
The com.example.library
and com.example.service
plugins both apply the com.example.java-convention
plugin:
plugins {
id 'java-library'
id 'maven-publish'
id 'com.example.java-convention'
}
plugins {
id 'com.example.java-convention'
}
plugins {
`java-library`
`maven-publish`
id("com.example.java-convention")
}
plugins {
id("com.example.java-convention")
}
Using classes from the main source set
Precompiled script plugins can use classes defined in the main source set of the plugins project.
In this sample, com.example.service
plugin uses a custom task class from src/main/java
to configure service README checks:
def readmeCheck = tasks.register('readmeCheck', com.example.ReadmeVerificationTask) {
// Expect the README in the project directory
readme = layout.projectDirectory.file("README.md")
// README must contain a Service API header
readmePatterns = ['^## Service API$']
}
val readmeCheck by tasks.registering(com.example.ReadmeVerificationTask::class) {
readme.set(layout.projectDirectory.file("README.md"))
readmePatterns.set(listOf("^## Service API$"))
}
For more details on authoring custom Gradle plugins, consult the user manual.