Preface: The goal is to replicate maven parent pom functionality, which applies plugins, repositories, configurations, and so on for projects that do not live on same repository.
I have a plugin which applies other plugins to the project, and configures some repositories, ala
class BarPlugin implements Plugin<Project> {
@Override
void apply(Project p) {
project.pluginManager.apply("java");
project.pluginManager.apply("jacoco");
project.allProjects {
configuration -> configuration.repositories { mavenCentral(); }
};
}
}
As far as as I'm reading the api, I cannot use such construct to add a plugin with given version, ex. plugin id 'com.foo.bar' version '1'
, because neither plugin manager, nor plugins properties have a method to apply plugin with given version, and the plugin must already exist on classpath before it can be applied like that.
After reading https://docs.gradle.org/8.11.1/userguide/sharing_build_logic_between_subprojects.html#sec:convention_plugins I've started to consider to converting the plugin into convention plugin, but it seems that the guide only touches about monorepository setups, where all the modules can see each other via common settings.gradle file. Is this applicable to multirepository setups? Is buildsrc
directory evaluated in that case?
No, plugins written in scripts within a project, so-called "convention plugins", are not easily shared across different projects.
You were already on the right track with your class-based plugin.
The way that you include other plugins via such a plugin (and also in convention plugins, incidentally) is indeed to add them to the classpath of your plugin and apply them by name or by class. The version of the dependency containing the compiled plugin code you add to the classpath determines the version of the plugin.
You add the plugin code to the classpath as a normal dependency as in any other project. We will be building our plugin in its own Gradle project and that project will have a build.gradle
file. In that file we specify a dependency of the artifact with the plugin's code in it. (This is not the plugin id used in the plugins
block, which is a different lookup mechanism used by Gradle which results in that same artifact being loaded.) If your plugin is published at the Gradle plugin portal then the coordinates of that artifact are those shown on the plugins page where it tells you how to use the 'legacy' method of plugin application.
As an example, take the Kotlin JVM plugin, published on the portal. We can add this to our plugin project as a dependency:
// build.gradle
dependencies {
// This determines the plugin version
implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0'
}
repositories {
// Needed if using this as source of artifact; artifacts may also be published elsewhere
gradlePluginPortal()
}
And with our plugin code, we can apply it (I prefer to use the class as it is type-checked):
void apply(Project p) {
p.getPluginManager().apply(KotlinPluginWrapper.class) // Using the class entry point for the Kotlin JVM plugin
}