8

Currently, I have a few utility functions defined in the top level build.gradle in a multi-project setup, for example like this:

def utilityMethod() {
    doSomethingWith(project) // project is magically defined
}

I would like to move this code into a plugin, which will make the utilityMethod available within a project that applies the plugin. How do I do that? Is it a project.extension?

Christian Goetze
  • 2,254
  • 3
  • 34
  • 51

3 Answers3

3

This seems to work using:

import org.gradle.api.Plugin
import org.gradle.api.Project

class FooPlugin implements Plugin<Project> {
    void apply(Project target) {
        target.extensions.create("foo", FooExtension)
        target.task('sometask', type: GreetingTask)
    }
}
class FooExtension{
    def sayHello(String text) {
        println "Hello " + text
    }
}

Then in the client build.gradle file you can do this:

task HelloTask << {
    foo.sayHello("DOM")
}

c:\plugintest>gradle -q HelloTask
Hello DOM

https://docs.gradle.org/current/userguide/custom_plugins.html

Domc
  • 150
  • 1
  • 8
  • This approach hasn't worked for me with Gradle 4.4. the `<<` is deprecated, so I used `.doFirst()` as well as declare the `HelloTask(){...}` itself. Then things worked. :) However, if plug-ins are not the _happy_ mechanism to provide common methods -- What is the way to provide reusable build tooling using Gradle?! – will Dec 30 '17 at 13:31
3

I implemented this recently, a full example is available at Github.

The injection basically boils down to

target.ext.utilityMethod = SomeClass.&utilityMethod

Beware:
This method could potentially conflict with some other plugin, so you should consider whether to use static imports instead.

Based on Answer 23290820.

Eero Aaltonen
  • 4,239
  • 1
  • 29
  • 41
0

Plugins are not meant to provide common methods but tasks.

When it comes to extensions they should be used to gather input for the applied plugins:

Most plugins need to obtain some configuration from the build script. One method for doing this is to use extension objects.

More details here.

Have a look at Peter's answer, using closures carried via ext might be what you are looking for.

Community
  • 1
  • 1
Opal
  • 81,889
  • 28
  • 189
  • 210
  • That actually does provide a way to go. The reason I want the method to be in the plugin is because it appears that's the only way I can access the project object, which sadly becomes unavailable if I don't define the function in the build.gradle itself. – Christian Goetze Mar 21 '15 at 15:03
  • See http://stackoverflow.com/questions/29184282/how-can-i-override-a-gradle-api-method why I'm exploring this... – Christian Goetze Mar 23 '15 at 16:12