Add a first class method to DSL


(Willie) #1

So i have this static method in a plugin

import static com.mystuff.iscool.lib.ProjectInfo.operatingSystem

Is it possible to register that operatingSystem method in the DSL so i don’t have to include the import in the gradle.build? basically i want

def d = dependencies.create(group: "jdk.${operatingSystem()}", name: 'oracle_x86', version: '1.8.+', ext: 'zip')

to work without having to import the method in the build file itself, just the act of applying the plugin imports it


(Stefan Oehme) #2

I’m pretty sure this is not what you want your buildscript users to write. The fact that dependencies are used for downloading VMs should be hidden in your plugin. The plugin should provide a dsl for defining which VMs to get. The OS should probably be automatically inferred.

Something like

platforms {
  openJdk8 {
    vendor 'openJdk'
    version '1.8.100'
  }
}

No matter what you decide to go with, the method you are looking for is Project.extensions() and (if you go with my suggestion) Project.container()


(Willie) #3

Oh im just learning at the moment. Playing with some code using the detatched containers that i found somewhere, trying to understand how this particular API works, all with a migraine going on.

I asked the questions because in addition to methods like the operatingSystem(), there are others we need to implement. Like we need a company specific reimplementation of mavenCentral() for example that changes its output based on command line patterns (aka, which environment is the build happening on) and other helper methods. Are there other ways to accomplish the same thing, sure, i can put them all into some plugin apply method. But, the thinking is the builds will seem a lot less like voodoo if we do something like

repositories {
  myCorpRepos()
}

rather than eliminate the whole block and move it into a plugin apply. Especially since every gradle tutorial out there says you should have that block. And thats also to say im not entirely sure how something ilke

buildscript{
  repositories {
    myCorpPlugins()
  }
}

would work as an apply method.

And again, this is one example. Its just one of those deals where it would be good to know how to register a first class citizen method in the DSL. It looks from the gradle code that its done with the java convention. But as of yet i haven’t found a way to initialize my own convention. Lots of moving parts there i don’t fully understand yet.


(Stefan Oehme) #4

If the repos should be the same for all your projects, then I’d totally move that into an init script shipped with a custom distribution. Everybody would point their Gradle wrapper to that custom distribution. I think repeating these definitions in every build script just invites mistakes and makes it harder to update if needed.

Project.extensions().create() is the way to add new DSL concepts to the project.

Conventions are an internal API, please don’t use them.

Adding methods to other parts of the DSL (e.g. the dependency block) has no statically typed API at the moment. You can do it with dynamic Groovy by using extra properties like this: dependencies.ext.foo = { /*a closure doing something */ }