Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ohohohoh Gradle. Making Android software turns this into a form of Stockholm syndrome, where you just get used to it. (And as some colleagues go, even pretend to like it. That is, until the next time it does something utterly stupid.) I have spent half a day trying to get a set of tasks to run depending on files that were changed since the original commit that started the git branch. This ought to be simple. Get all the files changed since the start, figure out their modules, figure out modules that have a dependency on those, run the tests only on those modules!

In Gradle-insanity land, you'll need a whole plugin for that. That you have to register in the buildScript.classpath closure. Wait, is it also in the plugins block of the root file ? But maybe also the modules themselves, as an apply. Or is it a plugin block too ? Oh wait, you're using buildSrc ? Well that's a whole other problem. Don't forget you need a basic .properties file in META-INF that just gives out the plugin's name so it can discover it through reflection instead of having a proper API to do so.

You would think the Kotlin scripts instead would fix it, but oh no. Not content with adding a solid 10 seconds every time gradle builds your model (which it rebuilds... Kind of when it feels like it), half of the pretended benefits of it simply do not exist. Almost all the documentation online is for the Groovy scripts, which is, obviously, incompatible with the .kts scripts. And I'm not just talking about syntax, no! Entire APIs are different. Setting a flag like `enabled = true` in groovy ? Have fun, we've added an isEnabled instead, because why not. Registering tasks? Wait, hold on, we've added new solutions in Kotlin! The existing APIs weren't batshit insane already, so let's abuse kotlin delegation. Kotlin's `by lazy {}` is nice and simple, why do we not make your write `val taskName by creating { }` ? And through some horrible logic, the name of your variable is what is exposed to Gradle. Or abusing the same thing for you to read things from a .properties file, because what is more clear than `val isFlagEnabled by project` ? Isn't it obvious that it's going to read a .properties file ? Not the values given through the -P flag when building though, because that would actually make sense. But wait! Let the gradle website explain to you the logic of lazy registered tasks. Why do you need these, you ask? Because Gradle is so absolutely terrible that having a large amount of tasks means they all get created when your daemon starts. Or when it performs anything.

Oh, right, you need a daemon because why would you not need to eat 1GB of RAM just to not have horrible startup times for a build tool? Load all the tasks, at all the times! Add a development flavor to all your modules ? lol you've just doubled your amount of tasks.

Let's add to this of course the absolute insanity that are the Android build tools. Making those work in a Makefile would be hell. aapt2, dexing... An absolute abomination of an amalgamation of bad tools (lol aapt2 silently ignoring your vector drawable overrides because it doesn't like the android:fillType attribute.) and horrible performance (aapt2 taking over a minute to process files on a medium sized project, or kapt (but that's a Kotlin problem) being awful in terms of performance.) All this to output a glorified .zip in the end. Or whatever new format's Google drug addled minds have invented to lock you in further to the Play Store and to make you give them your signing keys.

I am not a fan of Gradle. Or Android's build tools.



While Gradle does have a lot of issues, some of the things you mentioned are not correct.

> Don't forget you need a basic .properties file in META-INF that just gives out the plugin's name so it can discover it through reflection instead of having a proper API to do so.

Not really clear what do you mean, but declaring plugin names should not be done in properties, Gradle has syntax for declaring plugin ids inside its build config. If the plugin author haven’t used it, well, that’s on their conscience. Plugin users should never ever declare anything plugin-related in meta-inf.

> And through some horrible logic, the name of your variable is what is exposed to Gradle.

This is a feature of Kotlin as a language - in it, delegates know the names of the properties they are used for. `lazy` is just the simplest use of the delegates feature, which happens not to care about property names.

> Isn't it obvious that it's going to read a .properties file ? Not the values given through the -P flag when building though, because that would actually make sense.

This is simply untrue. Extracting properties this way most certainly will read them from .properties files and from all other sources of properties on a project, including the -P arguments.

Gradle does have a lot of issues, I can talk about them for hours (there are really nasty ones where there are no non-awful workarounds, for example, the built-in `tarTree` does not support symlinks in TAR archives, and there is no way to rebase the archive contents when extracting, i.e. to specify which directory of the archive to extract from, and these issues are very unlikely to be fixed, and these two are just the surface), but too many of your examples are somewhat wrong.


Android is very special indeed.

Not only has the Android team managed to push Gradle no matter what, they sell Android Java as the real Java.

They purposely use Android Java samples, with its half broken support for modern Java, as means to sell Kotlin in the platform, and when one points out the real differences, radio silence.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: