Defining a method in a root project does not appear in child projects

$SOURCE_ROOT/gradle/build.gradle:

def setProjectVersion(spec) {
    project.version = "$spec.${System.env.BUILD_NUMBER}"
}

parent/build.gradle:

apply from: "${System.env.SOURCE_ROOT}/gradle/build.gradle"

parent/child/build.gradle:

setProjectVersion '1.3'

Output:

FAILURE: Build failed with an exception.
  * Where:
Build file 'parent\build.gradle' line: 4
  * What went wrong:
A problem occurred evaluating project ':foo'.
> Could not find method setProjectVersion() for arguments [1.3] on project ':foo'.

Ok, I found out that imported methods are not inherited. I changed it to a closure, but it doesn’t have the behavior that I want:

$SOURCE_ROOT/gradle/build.gradle:

ext.setProjectVersion = { spec ->
    project.version = "${spec}.${System.env.BUILD_NUMBER}"
}

parent/child/build.gradle:

setProjectVersion('1.3')
  println project.version

Output:

unspecified

The ‘project’ you’re referring to in the closure is the project that is creating the closure. Have you tried something like:

allprojects {
   ext.setProjectVersion = { spec ->
       project.version = "${spec}.${System.env.BUILD_NUMBER}"
   }
}

‘project’ there will be for each project in the hierarchy (I think you were probably only setting the version on the root project before).

Perfect! I had moved it out of allprojects because I started out defining a function, and that is apparently not allowed inside the allprojects block (Groovy noob here). However, this seems to do exactly what I want, thanks!

No problem. I sort of think of the scripts as separate classes (so methods defined in there are local only to that ‘class’). I think allprojects {} might get turned into its own class too through an AST transform.

If there’s anything I want to carry around, I attach it to something that is more permanent (project, task, etc).

> I think allprojects {} might get turned into its own class too through an AST transform. 

This doesn’t happen. You can pretty much map this directly to ‘rootProject.allprojects.each {}’.

You’re right. I shouldn’t post while hungry.