Callback after plugin initialisation done and plugin extension configured?

Is there any callback that is fired after plugin initialization is done, but before all other build configuration code? And also after closed own plugi extension? I would like to use some features from another plugin, but afterEvaluate is too late.

plugins {
    `java-library`
    `maven-publish`
    id("my-plugin")
}

{callback here}

myPluginExntension {
   ...
}
{second callback here}

... rest of the buil.gradle file
1 Like

Take a look at this thread which discusses some lazy configuration techniques that can help you avoid afterEvaluate including

To be more specific I need to do this

the<PublishingExtension>().publications.whenObjectAdded {
 ....
}

It is already lazy, but it needs maven-publish to be initialized

So if I do this:

plugins {
    `java-library`
    `maven-publish`
    id("com.mycompany.myplugin") version "0.9.1-SNAPSHOT"
}

It always fails because my plugin is initialized first.
I will check your response if there is some way to replace the<PublishingExtension>() with something more lazy.

If my-plugin requires maven-publish to run before it, then my-plugin should apply maven-publish . Eg:

public class MyPlugin implements Plugin<Project> {
    public void apply(Project project) {
        project.apply plugin: 'maven-publish'
        MyExtension extension = project.extensions.create("extension", MyExtension.class);
        project.tasks.register("myTask", MyTask.class).configure(task -> {
            Callable<String> callable = () -> extension.property
            Provider<String> provider = project.getProviders().provider(callable);
            task.getProperty().set(provider);
        });
    }
}

There’s no need to worry about maven-publish being applied twice (eg once in your plugin, and another time in the client build.gradle) as Gradle applies plugins idempotently

2 Likes

Thanks! I will do it this way.
But what about if this dependency is optional?
I mean that my plugin can cooperate with another plugin only if it is available?
I can simply check the existence of PublishingExtension, but I cannot be sure because I don’t know the order of initialization.

PluginContainer extends DomainObjectCollection so you can hook into this to receive an event if/when the plugin is added

project.plugins.matching { it.class.simpleName == 'MavenPublishPlugin' }.all {
   the<PublishingExtension>().publications.whenObjectAdded { .... }
}

If maven-publish is never added to the project, the all {...} closure will never execute

2 Likes

Thanks a lot!
You saved my day.
It is even better. I meantime tried to use this (in Kotlin DSL)

project.plugins.whenPluginAdded {
    if (it::class.simpleName == "MavenPublishPlugin") {            
         ....
    }
}

but for some reason, this doesn’t work.

But this yes:
project.matching { it::class.simpleName == "MavenPublishPlugin" }.all {}

If you look at the javadocs for DomainObjectCollection

void all​(Closure) - Executes the given closure against all objects in this collection, and any objects subsequently added to this collection.

And

void whenObjectAdded​(Closure) - Adds a closure to be called when an object is added to this collection

With whenObjectAdded, ordering is important (I think). If you attach a whenObjectAdded listener after the object was added to the collection, you won’t get events for these objects (I think) and will only get notified for subsequent additions. With all and matching the order is not important (you always get the event)

2 Likes