Adding stuff to tasks when plugin order is unknown

This is something that I mentioned in my talk at Greach this year. I said that this is the only way I know of doing in this and if someone knows a shorter way I would love to hear about it. René might have mentioned something, but if he did, I forgot. Therefore the question is now on the forum.

This is for the case where when I want to perform an additional action on a task in another plugin, but I do not know in which order plugins will be applied by a script author or whether it even will be applied.

// Let's say I want to do add something to 'jar' task, 
// but only if the 'java' plugin is applied.
// If is not applied, I don't want to do anything i.e. 
// I don't want my plugint to force-apply 'java'.

 try {
  Task t = project.tasks.getByName('jar')
  // Handle the case where task already exist
  if( t instanceof Jar) {
    do_something_with(t)   
}
} catch(UnknownTaskException) {
  // Handle case for when task is added at a later stage
  project.tasks.whenTaskAdded { Task t ->
  if (t.name == 'jar' && t instanceof Jar) {
    do_something_with(t)
  }
}

Is there any shorter way of writing the above?

Hey Schalk,

you could do something like this:

class MyPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.plugins.withType(JavaPlugin) {
	     // add logic only if JavaPlugin is applied  (lazy evaluated)
             // no matter if applied after or before my own plugin
        }
     }
 }

cheers,
René

Hey René,

That’s find for something that ships woth Gradle, but what if I want to use ‘some.foo.bar.otherPlugin’ without creating a direct dependency on between my plugin and anotehr plugin.

For instance if I wanted to do something with John Engelman’s shadowJar, I can do

  project.tasks.whenTaskAdded { Task t ->
    if(t.class.superclass.name == 'com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar' && t.name=='shadowJar') {
      // Handle case for when shadowJar is added
    }
  }

which gets me around the dependency issue.

However I’m, not sure how I would achieve something similar using your example. I see there is a matching method, but it does not provide an option to provide an action as with withType.

You could use something like Class.forName() to check for the existence of the plugin on the classpath and conditionally then use plugins.withType() to register some configuration if the class exists.

1 Like

You could use

project.plugins.withId("com.github.johnrengelman.shadow") {
    //add your custom logic here
}

to avoid a direct compile dependency

2 Likes