Is it possible to put a groovy function into a file in buildSrc and simply call it from a task in the main build.gradle?

To preserve the readability of the build.gradle file Id like to move some helper methods into a seperate file in buildSrc, how do I call these from the build.gradle?

You can put any groovy class in buildSrc/src/main/groovy and it will be compiled and tested (if you also put something in “buildSrc/src/test/groovy”) and that class will be available to the build script.

I don’t know if there’s a way to define standalone methods.

Open up the User Guide and search for “buildSrc” for several references to this, most importantly chapter 60, “Organizing Build Logic”.

Your best bet would probably just to put those methods in a separate .gradle file and then do something like:

apply from: ‘gradle/helper.gradle’

Additionally, methods simply defined in the root of that file will not be immediately available to yours script. Easiest solution would be to add your helper methods as ‘ext’ properties.

In ‘helper.gradle’

configure(project.rootProject) {

ext {

foo = {

println ‘hello world’

}

}

}

The method ‘foo’ would then be available globally in your project.

1 Like

Thanks for the answers, I ended up making a really simple plugin to provide what I needed. Not sure if this is the best solution though?

Plugin:

import org.gradle.api.Plugin
import org.gradle.api.Project
  class SvnPlugin implements Plugin<Project> {
      @Override
    void apply(Project project) {
        project.extensions.create("svn", SvnRevision, project)
    }
}

Extension:

import org.gradle.api.Project
import org.tmatesoft.svn.core.wc.ISVNOptions
import org.tmatesoft.svn.core.wc.SVNClientManager
import org.tmatesoft.svn.core.wc.SVNRevision
import org.tmatesoft.svn.core.wc.SVNStatus
import org.tmatesoft.svn.core.wc.SVNStatusClient
import org.tmatesoft.svn.core.wc.SVNWCUtil
  class SvnRevision {
      String revision;
      public SvnRevision(Project project){
        this.revision = revision(project);
    }
      public String revision(Project project) {
        ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
        SVNClientManager clientManager = SVNClientManager.newInstance(options);
        SVNStatusClient statusClient = clientManager.getStatusClient();
        SVNStatus status = statusClient.doStatus(project.getProjectDir(), false);
        SVNRevision revision = status.getRevision();
        return revision.getNumber().toString();
    }
  }

Then I can use it like this:

versionFile.text = "rev ${project.svn.revision}) built by $System.env.USER@$hostname with Gradle at ${new Date().format('yyyy-MM-dd HH:mm:ss')}"

That’s a bit of a misuse of extensions. Extensions are meant as a way of extending the build script DSL. You are really just trying to add a dynamic property to your project. That is exactly what extra properties are for. Putting this in a separate gradle file would remove the code from you main build script, and allow you to avoid having to write a binary plugin as you did above. Your example, using the method I described above, would simply look like this:

configure(project.rootProject) {

ext {

svn = [

revision : {

ISVNOptions options = SVNWCUtil.createDefaultOptions(true)

SVNClientManager clientManager = SVNClientManager.newInstance(options)

SVNStatusClient statusClient = clientManager.getStatusClient()

SVNStatus status = statusClient.doStatus(project.getProjectDir(), false)

SVNRevision revision = status.getRevision()

revision.getNumber().toString()

}.call()

]

}

}

Thanks Mark, I have updated my build to use this strategy and it looks much cleaner.