Reacting to a plugin being applied would be done using pluginManager.withPlugin(...) { ... } without the need to use afterEvaluate which you should practically never use.
But actually applying plugins to subprojects is a bad-practice anti-pattern anyway that you should avoid.
Better provide convention plugins that apply the plugins you want and do the configuration you need and then the developers can simply apply that convention plugin to the projects where it is appropriate to have these conventions applied. Cross-project configuration harms more advance Gradle features and typically makes builds harder to understand and harder to maintain.
thanks for your answer!
using pluginManager.withPlugin(...) { ... } did the trick!
but i dont want to use bad partice - so i would rather elaborate my issue and maybe you can help me find a best practice solution to it-
my goal is to reduce the developers handling in the subproject gradle.
they will decide when pluginA is needed and add the corresponding task/scriptblock that pluginA provides.
I dont want to teach all the developers how pluginB works as it works the same and i want it to be changed in my parent project if needed
that said, i dont want all the subprojects to have these 2 plugins, only those that the programer decided that has pluginA, i want to add pluginB to them in order for my devops team to be able to use pluginB
since the if statement was written in my parent project i dont know which subprojects have that plugin
(well, i do now with the bad practice solution)
it might help to understand -
pluginA = is a typescript generator
pluginB = npm publisher
how would you approach this issue with best practices in mind?
note - im kinda new to gradle
You provide a convention plugin like com.company.typescript, this plugin will apply pluginA and pluginB and maybe also do some configuration all projects applying these should have. The devs then apply the com.company.typescript plugin which will implicitly apply pluginA and pluginB. The devs can then still configure the extension of pluginA as they like. Or you could even provide them an own extension that abstracts away logic they don’t need to care about and that your convention plugin then handles.
but then when i try to use this plugin in my subproject like so:
plugins {
id “com.company.typescript-generator”
}
i get the following error:
Exception is:
org.gradle.api.plugins.UnknownPluginException: Plugin [id: ‘com.company.typescript-generator’] was not found in any of the following sources:
Gradle Core Plugins (plugin is not in ‘org.gradle’ namespace)
Plugin Repositories (plugin dependency must include a version number for this source)
where do i set the plugin version ?
it seems like i need some very simple gradle configuration incapsulation and all i can find in the docs is more complicated version of plugin creation i dont need
it is just a typo on the post, the names are the same in the file system
does a gradle file in the buildSrc folder act as a plugin?
with no additional java classes?
Im doing exactly as the post you linked is showing but my gradle doesnt find the plugin…
this is in the root project
EDIT : ok so i made huge progress, my issue was i didnt have a build.gradle in my buildSrc project…
but my issue now is that i cant put the method i want to be defined in the “convention” plugin so every project that has it can use the convention plugin method
plugins{
id “cz.habarta.typescript-generator”
id “dev.petuska.npm.publish”
}
Caused by: java.lang.RuntimeException: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method npmPublish() for arguments [precompiled_TypescriptGenerator$_run_closure1@25f66c6e] on project ‘:project’ of type org.gradle.api.Project.
i might lack some basic understanding - but i thought that when ill specify the arguments in the convention plugin, any subproject that will use it wont have to, then i can simply call the npmPublish() on the subproject and the convention one will be executed.
am i wrong?
I’m not sure what you mean with your last sentence.
The plugins applying the plugin would not “call an npmPublish of the convention plugin” and your convention plugin also does not define any such method from what you showed.
But yes, what you showed in the example looks fine.
Any project applying that convention plugin will get this configuration done automatically.
That it does not work is most probably because you have wrong content in your npmPublish block.
But the content you actually showed seems to be fine to me.
So the problem is, that you post modified code with an error message you get from completely different code.
How should this enable anyone to sanely help?
One general advice I can give.
Do not use Groovy DSL, but Kotlin DSL.
Then you instantly have type-safe scripts and much better IDE support. At least when using a good IDE like IntelliJ.