A convention plugin has 2 flavors:
Precompiled script convention plugins
Standalone convention plugins
Not really.
A convention plugin just means a plugin with your own conventions that you apply where you want those conventions to be used, no matter where it is implemented, be it standalone published, or in a composite build, or in buildSrc
, or directly in the build, and no matter how it is implemented, be it a script plugin, a precompiled script plugin, a binary plugin written in Java, or Kotlin, or Groovy, or Scala, or whatever other language able to compile to JVM bytecode.
Precompiled script convention plugins are placed in the projects itself.
They are never “in the projects themselves”, they are always in a separate build. Whether it is a buildSrc
build, or a build included as composite build in the same repository as the project where it is used, or in a completely standalone build that you publish to use it in other builds is irrelevant.
But what we need is a convention plugin that is stored in a central location of our infrastructure and can be used by all teams.
As I said, you can still write the plugin as precompiled script plugin, or as normal binary plugin using and JVM language, and then for example publish the result to some repository to use it in the other projects.
We don’t know which of the “wrapped” plugins will be used, by the varous projects. The only think we need is a kind of contract for the developer: If you use the convention plugin you can be sure, that all offered plugins you apply are working.
Well, you can write the convention plugins in a way that they react to which plugins are applied and do not apply plugins themselves. That’s what you do with pluginManager.withPlugin("...") { ... }
to just react to a plugin being applied and configure it according to your conventions.
Or you can have multiple convention plugins, for example one per “wrapped” plugin and the project applying your convention plugins can choose which ones to apply.
If your main concern is to streamline the used versions, you can also write a central version catalog and / or platform. Both can be published too and then used by other builds.
In order to use it you must must do a publishToMavenLocal to get a defined version Id for this plugin.
Why publish to maven local and not use it also via composite build like the other?
Btw. using mavenLocal
is quite problematic and should be avoided wherever possible and usually if really needed it is better to use some dedicated file-based repository or at least defined using repository filter exactly which dependencies should be taken from mavenLocal
.
And why do you apply one of the plugins properly using the plugins { ... }
block and the other using the legacy apply plugin:
(resp. apply(plugin =
) that you should practically never use?
But there is a race condition in consumerKotlin. The dependencies closure is evaluated before the mcve-java-plugin-kotlin has been evaluated. The consumerKotlin is exiting with an error.
That’s not correct.
Your plugin is evaluated first.
I didn’t execute and you didn’t write the error, but I guess the error is, that it does not find implementation
.
That is because you do use the legacy approach using apply(plugin =
as mentioned above.
For plugins applied that way no type-safe accessors for the Kotlin DSL are generated. Those only exist for plugins properly applied using the plugins { ... }
DSL.
Is it possible that the groovyConsumer just works accidentally?
Groovy is an extremely dynamic language with duck-typing.
At runtime the plugin is applied and thus the implementation
call can be found and thus succeeds.
Kotlin is not runtime-dynamic like that, but is type-safe, so needs the proper accessors generated, which is not done in your case as explained above, so the compilation already fails.
Btw. you should practically never use the all
distribution, but always bin
.
There is exactly one situation where the all
distribution is useful.
That is when you use the Groovy DSL (which I advise against anyway) and even then only while editing the build scripts to work-around an IDE shortcoming.
Other than that, the all
distribution just wastes time, bandwidth and diskspace for anyone and anything just executing the build.