I often use supplementary .gradle files to apply standard behavior that subprojects can use or not as appropriate. For example I might have a gradle/publishing.gradle with all the config for the Bintray plugin, a gradle/junit.gradle with all the config for testing, etc. If a sub-module needs that behavior I can include it with apply from: "$rootDir/gradle/publishing.gradle.
I’m attempting to port my project’s build to the Kotlin DSL and finding it almost impossible to follow this pattern. Problems I’m running into are:
If I add the plugin in the sub-project’s build.gradle.kts the included files can’t reference the plugin’s classes or DSL extensions.
If I add the plugin using a plugins block in the included file, the same is true.
If I create a buildscript block in the included file with a classpath dependency on the plugin then apply the plugin by class (e.g. apply<NebulaKotlinPlugin>()) I can reference classes and get the DSL to work but I can’t override config in a particular subproject (e.g. referencing an external lib’s documentation URL in Dokka config) because then the subproject build.gradle.kts can’t reference the DSL/classes of the plugin.
If I apply the plugin or use a buildscript block in both the build.gradle.kts and the included file the scripts compile but fail at runtime as the plugin’s classes are loaded with separate classloaders.
I don’t think I can be the only person who’d want to do such a thing. The only alternatives seem to be copy-pasting common config into every sub-project’s build.gradle.kts or applying everything in a subprojects block in the root build.gradle.kts which assumes every subproject needs all the same things.
The samples don’t show this well, but the way to do this is to put script plugins into buildSrc/src/main/kotlin. The plugin ID is equal to the file name. They are then compiled like a normal plugin in buildSrc, minus the boilerplate class definiton. If you need any external dependencies for your plugins, they should be dependencies of buildSrc.
@eskatos there should be a sample for this. The precompiled plugin sample is too complicated for what most people want. The buildSrc samples on the other hand only show traditional plugins. An “organizing build logic” sample would be ideal.
I’ve added one at that location called publishing.gradle.kts added id("publishing") to my subproject’s build file but I just get Plugin [id: 'publishing'] was not found in any of the following sources:
Edit: never mind. Needed to add kotlin-dsl to the buildSrc itself. I have other errors now but at least it seems to be finding the plugin.
I’m not clear what I need to put in the file. Everything I’m trying is unrecognized.
Should I include plugins using the plugins { id("whatever") } DSL? Or by including them on the buildSrc compile classpath and then trying to apply them by type? I’ve tried both with no success. Some other way? An example here of a project that already does this would be super helpful.
I can get somewhere with @ljacomet’s method but there’s some boilerplate involved so I’d love to understand the script plugin approach.
There still is some ceremony to use precompiled script plugins. Agreed that the project-with-buildSrc sample should be enhanced to demonstrate this. The precompiled-script-plugins do demonstrate their use but in a “binary plugin” context instead of for local build logic. We’ll look into that.
In the meantime here are some instructions for using precompiled script plugins in buildSrc:
#1 add to your buildSrc/build.gradle.kts:
plugins {
`java-gradle-plugin`
`kotlin-dsl`
`kotlin-dsl-precompiled-script-plugins`
}
dependencies {
// the dependencies used by your precompiled script plugins
}
#2 create a precompiled script at buildSrc/src/main/kotlin/my-plugin.gradle.kts
plugins { // Can use the plugins block but dependencies must be declared, see above
java
id("some-other-plugin")
}
// Custom build logic
#3 in your build scripts, you can then apply the my-plugin plugin, e.g. in sub-project/build.gradle.kts:
plugins {
id("my-plugin")
}
All build scripts can see classes from plugin coming from buildSrc.