4 ms·
I work on a large codebase that uses Gradle. We're occasionally held up as an example: "see? This corp uses Gradle for something this large, so it must be good.
by shaftway 4y ago
I work on a large codebase that uses Gradle. We're occasionally held up as an example: "see? This corp uses Gradle for something this large, so it must be good." We have a regularly scheduled meeting with Gradle where we have in the past influenced their feature prioritization. We also have a former Gradle engineer on staff.
Gradle is such garbage. I can't count the number of times our ex-Gradler has said "you're not going to like the answer..."
Everything is action-at-a-distance and implicit. You can't answer basic questions like:
- Why does this task exist?
- Why does this task depend on this other task?
- Why did this file get included or excluded?
- How did I get 4 dependencies on 4 different versions of the same library?
You can't answer this stuff because some random include file in some random place reached into a task that had already been created and modified it. And there's no way to find out where this happened. I don't understand why you would want a build system that has build tasks that are mutable.
And yes, it would be nice if people wouldn't do action-at-a-distance, or would not do weird stuff to tasks after they've been created, but that's not really possible. We've actually gone through the trouble of writing a linter that makes sure that devs aren't doing anything too crazy in their .gradle files. But of course some files have to do crazy stuff, so there's an escape hatch, so everyone just uses that.
- kaba0 4y ago> that has build tasks that are mutable They are not mutable.. their configuration is. That’s like the whole point of gradle. Also, people should just learn to write plugins - that’s the proper way to add functionality.
- wiseowise 4y agoDon’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.
- Jolter 4y agoThen maybe Gradle should do what Maven does and disallow writing code in the configuration?
- misja111 4y agoIt'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.
- shaftway 4y agoThis 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.
- kaba0 4y agoThe 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.
- piva00 4y agoThat'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. Same issue I had with Ruby and Scala codebases...
- kaba0 4y agoBecause no one understands it, and they end up with tasks that run at config time, and eternal pain. Gradle really should fix their documentation though, as even though people are at the wrong here, if everyone is misusing it something is not fine.
- piva00 4y agoGradle 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.
- shaftway 4y ago> They are not mutable.. their configuration is. That's just a mutable task with more steps. If I create a task and then later can reconfigure that task, that's a mutable task. Arguing that it happens during the configuration phase is just semantics. It's still mutable and action-at-a-distance. Is there another popular build system that allows this? > Also, people should just learn to write plugins - that’s the proper way to add functionality. I'm not sure I agree. It puts your weird behavior inside an opaque binary. If your plugin needs any sort of configuration whatsoever then you've got a ton of boilerplate to write to make the DSL "just work". The original article actually calls this out: > The whole idea of using community-developed plugins becomes a minefield because the chance of them applying all of the concepts completely correctly is essentially 0%, meaning you might be okay as long as you’re only doing basic stuff, but as soon as you stray off the beaten path stuff starts breaking and you have almost no chance to fix it properly yourself. I don't see any reason why I'd be better at writing a plugin than other people in the community.
- nvarsj 4y agoHave you written a gradle plugin? It’s like a dark art. The gradle internals are a poorly documented, complicated magical mess. I wrote several gradle plugins used by 1000+ devs and I’m about the only one who understood how gradle worked in my whole org - and that was after spilling some serious blood. One of the most poorly overdesigned OSS tools I’ve ever worked on. I also did a lot of maven dev and it was way easier to work with. (TBF this was about 5 years ago so maybe it has improved.)
- brabel 4y ago> (TBF this was about 5 years ago so maybe it has improved.) No, it's gotten worse. They've deprecated most of what you know from 5 years ago and now have different ways of doing the same thing. Not better, except it's probably more "performance friendly" as that's been their priority lately, to make Gradle perform as well as the competitors... mostly, it's just different and even more black arts now as you're forced to use Providers, inject dependencies and so on.
- doctor_eval 4y ago> Everything is action-at-a-distance and implicit. And this was the idiomatic way to build "enterprise" software a few years ago, right? Inversion of control, automatic dependency injection, service discovery, configuration over code, builder patterns, ORMs, DSLs, and on and on. The idea seemed to be that, if we just keep adding abstraction and complexity to our tools, soon enough we would be able to build an entire systems with one just-so line of code. I'm not justifying it, but Gradle really was a product of the times. I used it for years but never understood it, and always hated it only slightly less than Maven. It's like we got captured by the tools.
- 411111111111111 4y ago> this was the idiomatic way to build "enterprise" software a few years ago, right? Inversion of control, automatic dependency injection, service discovery, configuration over code, builder patterns, ORMs, DSLs, and on and on. All of that remains true for enterprise today as well. And for the record, Gradle doesn't really check any of the marks you just listed, only DSL if you are squinting a little. Gradle is basically a application to run generic groovy code. There are literally no limits to what you can do, as you've got a full JVM to play with.
- doctor_eval 4y agoRight, but running code to create configuration for other code, which is how I remember the build system working, is the same kind of inception-like abstraction that I was referring to. As to that "no limits" thing: I see that as part of the problem and complexity of using Gradle. Everything is abstract and open. But at the point where you can do literally anything, maybe we'd be better off with a build library that we could just call from whatever language we're using? Why do we need another language to do "literally" anything?
- 411111111111111 4y agoI'd agree that a lot of the SMB/large enterprise software devleopment practices make trivial domain requirements into extremely complicated distributed monoliths colloquially called "microsrevices", but gradle is a pretty bad example for this kind of behaviour. gradle was created as a kneejerk reaction to maven forcing build configuration to be set in stone and in xml. Its inspired by dynamic scripting languages, which is as far removed from these companies as you can get. I remember it being created shortly after groovy became massively overhyped, and I think the only tools still using it are gradle and Jenkins...