In our update in November 2023, we announced a new experimental project called Declarative Gradle.
That post introduced our ideas for a developer-first software definition and how we planned to fulfill our vision for a declarative build language for Gradle.
Since then, we’ve been working hard to create the first early access preview (EAP) of Declarative Gradle.
You finally get it right. A declarative approach is far better than a scripting approach. Maven actually did it right by rescuing us from the horror of Ant build scripts, but Gradle, on the contrary, pulled us back to it just because Groovy looked so powerful and promising at that time.
I like the syntax. I realize though that I’m not certain that it’s the right idea. I think you should try seeing how it well it would serialize to/from something like yaml/toml. One of the reasons I have for this is Jetbrains isn’t the only ones that need to parse this. I was just responding to someone on slack about troubles with VSCode. Red Hat supplies that plugin but last I checked it still doesn’t support syntax highlighting for Kotlin DSL making it almost impossible to edit. For a very long time it didn’t even support classpath for kotlin DSL. Alternatively I know that kotlinlang, and typescript support language servers, perhaps you should ensure you provide a to spec (whatever) language server that could be used by any IDE.
We think yaml/toml doesn’t solve the bigger problem, which is understanding the model. The model is really only understood by the plugin that defines it. If you control every side (plugin, IDE, other integrations), you can just pay the cost of keeping everything in sync. Gradle doesn’t have that luxury because we want the plugin (and model) to be extensible and for tooling to go back to the source of understanding instead of making assumptions/reverse engineering. Those assumptions get in the way today.
There are several use cases that look like they all need to “parse the file”:
Syntax highlighting
Semantic highlighting and auto-complete
Import/sync/project information
Modifications
Syntax highlighting is essentially static for the language. Semantic highlighting and auto-complete needs schema information that can only be provided by the model. I think neither of these are easier with TOML/YAML as the language users work in without something special to interact with Gradle.
WRT import/sync, I think it’s very alluring to see something like:
java:
targetJdk: 18
And say, aha, I can parse this and know that we’re building Java code and it’ll use Java 18 language features. Maybe that’s true in version 1.0, but in 1.1, sourceLanguage was made configurable:
java:
targetJdk: 18
sourceLanguage: 8
Now the earlier assumption is wrong. The idea is that what’s written in the file (in whatever language) is not 1:1 the same as the model needed for understanding.
You can imagine similar scenarios with modifications.
WRT your point about other tools, our intention is to provide a language server for DCL that would provide highlighting and auto-complete. Maybe some kind of mutations/automated modification support–how this works with language servers is unclear. Tooling would still need to go through the usual Import/Sync process otherwise.
Time will tell, but right now, I’m experimenting with Polyglot Maven because I find myself spending far too much time on Gradle for tasks that should be straightforward.
For example, I recently tried to configure JaCoCo to run individual verifications for each subproject, rather than the entire repository. This required merging my white-box and black-box test suites, which are both integration tests and not typical test types. Even with @Vampire’s help, we couldn’t get it to work. Gradle has turned into a time sink for build engineering, which isn’t even my main responsibility. I’ve gone so far as to wrap the Gradle build with a Makefile just to streamline execution.
I also think there might be some over-engineering at play here. A more “KISS” approach could be more effective. How much less time would be spent creating something functional using YAML, rather than building a language server and addressing non-core plugins? In my view, core plugins should be separated from the core itself. For instance, Checkstyle is blocked from optimizations due to API breakage concerns, even though the API could simply be deprecated and ignored within the task. Versioning it separately would allow for upgrades without holding back the tool.
It’s unfortunate that Java still lacks a truly modern build tool. Even 15 years ago, Perl seemed to be doing better than Gradle does today. While I’m not sure where Perl stands now, its Dist::Zilla was a better solution at the time. I’m not saying Maven is the answer, but I’ll find out over the next week. The polyglot extension, at least, feels like a significant improvement.
I’ve shared my thoughts, now it’s time to focus on getting things done. Cheers!