Don’t know why this is downvoted when it’s the truth.
Build scripts are there to just configure stuff.
Gradle is literally combination of tasks, plug-ins and artifacts.
Gradle suffers the same issue I had with Ruby codebases some 10-12 years ago: people want to be clever, the tooling is very powerful, people use the powerful features to create idiosyncratic tricks: auto-loaders, reconfigurations, and a multitude of action-at-a-distance clever tricks which are inscrutable after it gets large enough.
The ergonomics of Gradle allows to create monstrosities that are extremely hard to reason about later. I've lost countless hours in previous jobs using Gradle where someone at some point of the project tried to engineer the build system as an application, an application that is hard to read, reason about and actually know what it is doing.
Build scripts should be declarative, simple to read and follow. Not a plethora of imports and reconfigurations happening under the hood creating a massive cognitive load to simply understand how the fuck a JAR is built.
It's a pity that this comment is somewhat buried, because it is so true.
Loads of people complain about Maven, because writing custom logic in it is hard. If you do want to add some custom conditional steps into your build, you have to somehow squeeze it in your pom file using plugins and xml configuration.
But the thing is, because adding custom logic is so hard, Maven builds are pretty easy to understand. And as in all other area's of software development, easy to understand means easy to change and easy to maintain.
This is the approach we take with our linter. And it sucks. Because sometimes you really do want to have a code approach. Our remote cache rules have a couple twists (developers can read from remote or read/write to local, presubmit server doesn't use cache at all, and CI does read/write to remote. Yeah, you could code that all up into a plugin, but the rollout strategy for plugins isn't the cleanest. And it would just be more hidden, opaque, implicit behavior.
The actual configuration-time evaluated code that should be in your build files is almost zero, besides some if-else for configuration. That’s the intended use of Gradle build files.
That's not how people use Gradle though, it's a footgun, it's happened over and over in my career that Gradle build files were extremely hard to parse and understand as a human. That is a failure of the tool, it allows people to do that so people do it.