Obviously a contrived example, but the intention is to create a new DSL block (“things”) that associates information with native Gradle configurations in a manner similar to the “dependencies” or “repositories” blocks do.
I made a small bit of progress by defining a method in my build script that delegates to a custom “handler” that I created in a manner similar of DefaultDependenciesHandler:
void things( Closure configureClosure ) {
ThingsHandler thingsHandler = new DefaultThingsHandler(configurations)
That seemed to work (aside from me needing to move the thingsHandler instantiation out of the method). But I don’t know how to get my plugin to define the new “things” method at the project scope. This question could have been posed as “How do you code a plugin to add a method to the Project?”. Thanks for any pointers…/rob
Thanks for the pointer. I got something working by creating an extension object from a custom “configuration” class (though I don’t know if that terminology is still current in gradle-1.0). My convention class contained a field for a “handler” object that implemented methodMissing as you suggested. I patterned it from the DefaultDependencyHandler in the gradle source. So I ended up with something like this:
class MyPlugin implements Plugin<Project>
{
void apply(Project project) {
project.configure(project) {
extensions.create("mystuff", MyConvention, project)
}
}
}
class MyConvention {
DefaultThingHandler things
def MyConvention(Project project) {
this.things = new DefaultThingHandler(project)
}
void things(Closure configureClosure) {
ConfigureUtil.configure(configureClosure, this.things)
}
}
class DefaultThingHandler {..} // patterned off of Gradle's internal DefaultDependencyHandler
So although I dont have a first class “things” object at the same level as “repositories” or “dependencies”, I get the next best thing:
The ‘MyConvention’ stuff was only necessary before extensions came along. Instead, simply do ‘project.extensions.things = new DefaultThingHandler(project)’, and use it like this;
things {
// configure DefaultThingHandler in here
}
‘DefaultThingHandler’ doesn’t need any special methods to make this work. Also see the “Writing Plugins” chapter in the Gradle user guide.
things {
myconfig name:'whatever', colour:'black', price:'59.95'
}
but it didn’t work because “things” was not found to be a method taking a Closure argument:
> Could not find method things() for arguments [sample_4p96i3djuvadhncfl6iatdnskb$_run_closure5@1408325] on root project 'myPlugin'.
I tried this before and assumed it could not be done, which is why I went back to creating my “convention” class containing a field for the DefaultThingHandler object.