NOTE: You can open this sample inside an IDE using the https://www.jetbrains.com/help/idea/gradle.html#gradle_import_project_start[IntelliJ native importer] or https://projects.eclipse.org/projects/tools.buildship[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 a multi module project produces multiple Java libraries that use shared internal modules as an implementation detail.
We want to apply a set of code quality checking rules to all the submodules and configure some aspects specific to library artifacts.

This is achieved by layering two separate plugins in project's `buildSrc` module:

* `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 and checks for mandatory content in a README.

All plugins created in this sample contain functional tests that use link:{userManualPath}/test_kit.html[TestKit] to verify their behavior.

This sample does not have any project source code and only lays out a hypothetical project structure where two library modules depend on a shared internal module.

The internal module uses `com.example.java-convention` plugin:
====
include::sample[dir="groovy",files="internal-module/build.gradle[]"]
include::sample[dir="kotlin",files="internal-module/build.gradle.kts[]"]
====

The two libraries use `com.example.library` plugin that in turn uses `com.example.java-convention`.
====
include::sample[dir="groovy",files="library-a/build.gradle[];library-b/build.gradle[]"]
include::sample[dir="kotlin",files="library-a/build.gradle.kts[];library-b/build.gradle.kts[]"]
====

== 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 link:{userManualPath}/custom_plugins.html#applying_external_plugins_in_precompiled_script_plugins[need to be added as implementation dependencies] before they can be applied in a precompiled script plugin:
====
include::sample[dir="groovy",files="buildSrc/build.gradle[tags=repositories-and-dependencies]"]
include::sample[dir="kotlin",files="buildSrc/build.gradle.kts[tags=repositories-and-dependencies]"]
====

* 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:
====
include::sample[dir="groovy",files="buildSrc/src/main/groovy/com.example.java-convention.gradle[tags=apply-external-plugin]"]
include::sample[dir="kotlin",files="buildSrc/src/main/kotlin/com.example.java-convention.gradle.kts[tags=apply-external-plugin]"]
====

=== Applying other precompiled script plugins

Precompiled script plugins can apply other precompiled script plugins.

The `com.example.library` plugin applies the `com.example.java-convention` plugin:
====
include::sample[dir="groovy",files="buildSrc/src/main/groovy/com.example.library.gradle[tags=plugins]"]
include::sample[dir="kotlin",files="buildSrc/src/main/kotlin/com.example.library.gradle.kts[tags=plugins]"]
====

=== 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.library` plugin uses a custom task class from `buildSrc/src/main/java` to configure library README checks:
====
include::sample[dir="groovy",files="buildSrc/src/main/groovy/com.example.library.gradle[tags=use-java-class]"]
include::sample[dir="kotlin",files="buildSrc/src/main/kotlin/com.example.library.gradle.kts[tags=use-java-class]"]
====

For more details on authoring custom Gradle plugins, consult the link:{userManualPath}/custom_plugins.html[user manual].
