Gradle init script and beforeProject / allprojects

Hi. I have been reading Good Neighbors: How to Reduce Maven Central Traffic from Gradle Builds and we need something similar for our corporate proxy although it needs to be compatible with multiple versions of Gradle hence thinking it should be implemented in Groovy to avoid issues where e.g. getDependencyResolutionManagement is not available in earlier versions so I can wrap it in

        if (org.gradle.util.GradleVersion.current() >= org.gradle.util.GradleVersion.version("6.8")) {
....

However what isn’t clear from searching and reading the javadoc is the difference between gradle.beforeProject/afterProject and allprojects i.e. if using the former will it apply to all modules in a multi-module build including any composite plugins?

Which is preferred to use and why? It would be really helpful if this could be expanded upon in the docs :slight_smile:

Thanks

we need something similar for our corporate proxy although it needs to be compatible with multiple versions of Gradle hence thinking it should be implemented in Groovy to avoid issues where e.g. getDependencyResolutionManagement is not available in earlier versions so I can wrap it in

Besides that it might be best if those projects use the proxy directly - unless you share those projects with others of course - I agree. If implemented as init script I would usually also use Groovy DSL. One point is compatibility with Gradle versions not yet supporting Kotlin DSL, the other point is what you mentioned, that you can more easily do Gradle-version specific code due to the duck-typing of Groovy.

However what isn’t clear from searching and reading the javadoc is the difference between gradle.beforeProject/afterProject and allprojects

The difference is described in the JavaDoc.
To best understand it, take a build with two projects and paste this in the root project build script:

gradle.beforeProject {
    println("beforeProject ${this.path}")
}
gradle.allprojects {
    println("allprojects ${this.path}")
}
gradle.afterProject {
    println("afterProject ${this.path}")
}

You will see that like described in the JavaDoc, allprojects works on all projects, already existing ones and also ones added in the future. The other two only work from the point of adding on, so beforeProject will only be called for the subproject, afterProject will be called for the root and subproject.

When registering those from a settings or init script, there is not much difference as to which projects they apply to as you are still in initialization phase and they are only called at configuration phase. From there it is just when the code is called, before the build scripts or after them.

including any composite plugins

Not sure what you mean with “composite plugins”, but whether you mean composite build that builds a plugin or all composite builds is not really important. If you do it from the settings script, then not as the composite builds are stand-alone builds, if you do it from an init script then of course yes, because the init script is also applied to the composite build itself.

Which is preferred to use and why?

The one that best fits your use-case :slight_smile:

Thanks so much for your reply (and on the weekend!!) I’ve replied inline…

Without digging into our scenario too much we can’t easily modify the projects in question so the init script seemed to be the way forward. Thanks for the point about Groovy versus Kotlin - it perhaps would have been helpful if that blog post gave examples in both kotlin and groovy ?

I think I see - you’re saying the behaviour is subtlety different when they are used within the project but for my use-case - using them within the init.gradle they are all called in config phase according to Build Lifecycle

It would be rather useful if that lifecycle page also described when the init script is hooked in (and its not clear on the phase in Initialization Scripts either ). Would this be suitable as a small documentation enhancement or have I missed a sentence somewhere?

Apologies, I meant Composite Builds And yes, I want the init script to apply to everything so thanks for clarifying.

I have tried your printouts and sure enough, in a multi-module build, the projects are identical for allprojects/before/after. My use-case is to have the the init script be applied to every project in a multi-module build - the blog entry seemed to prefer beforeProject/afterProject versus allprojects but it appears there is no difference from the point of view of an init script - is that correct? Why did the blog post choose that route as opposed to simply using the allprojects API?

Thanks

Nick

and on the weekend

Why not?
I’m just a user like you.

it perhaps would have been helpful if that blog post gave examples in both kotlin and groovy ?

Possible.
Each blog post has a thread associated with it, feel free to post to it, but I have no idea whether the Blog author will react. :man_shrugging:

It would be rather useful if that lifecycle page also described when the init script is hooked in (and its not clear on the phase in Initialization Scripts either). Would this be suitable as a small documentation enhancement or have I missed a sentence somewhere?

Quite possible, feel free to open a documentation request.
As I said, I’m just a user like you. :slight_smile:

Why did the blog post choose that route as opposed to simply using the allprojects API?

You should ask in the thread associated with that blog post. Hopefully the blog author can answer your question. I’m not a psych, so unfortunately cannot know why the blog author chose one over the other, sorry.

Indeed

I’ll enter a ticket requesting some small documentation clarifications

Thanks for your help