How can I call a function from Gradle's `pluginManagement {}` block?

Unfortunately, it still doesn’t work, and the error only got less helpful:

It says the property you try to reference is not found, as there is no such property anymore as you made it a method.

If you would instead try to call the method, it would tell you that the method is not found.

I’m pretty sure it has to do something with how to pluginManagement {} block is treated by Gradle in a special way (that is, it’s evaluated first, before the rest of code in settings.gradle is evaluated)

Exact, it is extracted and evaluated separately.
The pluginManagement block can define plugin repositories or include builds with settings plugins, so to compile the rest of the script, it needs to be evaluated first separately.
Which is also the reason you cannot use properties or methods from outside the block.
It has to be self-contained.

I thought that maybe all code that’s before the pluginManagement {} block is somehow stripped (?), so I tried creating a class with a static method in it:

As I said, all is “stripped”, otherwise you could also simply define the method after the block and call it.

I think a Gradle Settings Plugin could work here, but I’d prefer not to do it unless necessary.

No, it wouldn’t help due to hen-and-egg problem.
settings plugins are evaluated after the pluginManagement block as that block can define included builds with settings plugins or repositories where to find settings plugins, so a settings plugin is too late to configure that block.

PS I’d also happily accept an explanation as to why I got an error early in attempt 1), but not in attempt (2).

Not sure what you mean by “early”, both errors come more or less immediately.
Just in attempt 1 you had statements before the block which is disallowed in Groovy DSL (it is allowed in Kotlin DSL but wouldn’t work either to be used inside the block) and thus get an error while parsing the script to extract the block, while in attempt 2 you get an error when actually evaluating the block as it uses a property that does not exist.


You can do what you want to achieve by using “extra” properties.
Using them is usually a code-smell and a just a work-around for not doing something properly, but this might be one of the rare cases where its use might be appropriate.

While the pluginManagment block is evaluated separately standalone, it can still modify the model, so you can add a closure as extra property that is then also available to the remaining script:

pluginManagement {
    settings.ext.foo = { "Foo" }
    println("1: ${foo()}")
    includeBuild("${foo()}")
}

println("2: ${foo()}")
1 Like