DEV Community

Jean-Michel 🕵🏻‍♂️ Fayard
Jean-Michel 🕵🏻‍♂️ Fayard

Posted on • Updated on • Originally published at proandroiddev.com

Better dependency management in Android Studio 3.5 with Gradle buildSrcVersions

Android Studio 3.5 is released! Have you updated yet? Go to https://developer.android.com/studio, I will wait.

Personally, I'm most excited not by any new feature but by a bugfix which makes relevant again for android developers my open-source project for managing dependencies.

GitHub logo Splitties / refreshVersions

Life is too short to google for dependencies and versions

What is refreshVersions?

refreshVersions helps Gradle users with the tedious manual work usually involved in adding and updating dependencies and their versions.

Documentation

See documentation at https://splitties.github.io/refreshVersions

Setup

// settings.gradle(.kts)
plugins {
    // See https://splitties.github.io/refreshVersions
    id("de.fayard.refreshVersions") version "0.60.5"
}

refreshVersions { // Optional: configure the plugin
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Read the friendly documentation

Usage

Make sure the project is correctly set up (see just above).

Migrate project:

The refreshVersionsMigrate task can help you migrate your project in a few minutes, or less.

In version 0.50.0, support for Gradle's Versions Catalogs was added (see discussion thread here), so a --mode option is now required.

Run it without it to see the complete list and the full description of…

This project was born out of a growing disgust for this dark corner of Android Studio:

🙀 Gradle project sync failed. [Try again] 🙀

"Try Again" is kind of misnomer here.

Android Studio support for editing the Gradle files was bad 😿

Android Studio is in general a magnificent IDE, and integration with Gradle is an essential component of it. So you would expect to have great tooling support for editing your build files.

Instead, this error message is the exact moment where it all breaks down. Instead of Try Again, the wording should be more something like: "You have some error, somewhere, and you are on your own to fix it. Good luck, and tell me when you think you are done.".

The developer experience becomes more like something you would expect from the JavaScript world. You copy/paste some stuff from some website, hopefully at the right place (which is non-trivial!). Hoping for the best, you run it and a cryptic error message is thrown. Rince and repeat.

Why is the tooling so bad? Pretty much the same reasons that in the javascript world: we are doing lots of meta-programming stuff (with Gradle plugins) using a dynamic language (Groovy).

Gradle has the right long-term plan to overcome this problem: write less Groovy and more Kotlin.

But while Kotlin is probably the future, Groovy is the present. And we need some incremental progress to help us here and now with our existing builds.

The Gradle "buildSrc" module 😼

With Android Studio 3.5, the Gradle "buildSrc" module comes to the rescue.

The "buildSrc" is a Gradle module where you can write Kotlin code like usual (with full tooling support). That code is then be available to all your build files - not your final application. Crucially IntelliJ IDEA and Android Studio have good support for calling it from build.gradle

You can put all the things there that are a bit complicated or should be reused, and keep your build.gradle files nice and tidy.

The main use-case I had in mind was to replace those Groovy libraries.gradle files we used to write:

That's quite straightforward but... do I have to write all this code manually?

Laziness is one of the three great virtues of a programmer, so I wrote a plugin which asks Gradle which dependencies my project is using and let the KotlinPoet generate those files.

Gradle buildSrcVersions 😸

Install the plugin by editing your root build.gradle(.kts) file like this:

The plugin adds a task to your build, also called :buildSrcVersions.

Run it like this:

Sync your Gradle build.

You can now start to replace your magic strings with the properties available in Libs.kt

Finally the IDE tooling we deserve:

  • auto-completion
  • jumping to definition
  • ...

But the more important half of what the plugin do is looking automatically for you what are the newer versions available for all your dependencies!

😻 Search for dependencies updates

Upgrade dependencies tend to be tedious. But it is really important to manage them properly. Here are some reasons:

  • Few projects have versioned documentation: master/README.md is their documentation. This means you can waste time trying out snippets that do not work in the version you are using.
  • When you open an issue, you will often be asked: Can you reproduce this problem in the latest version?
  • On the other hand, you don't want to break your app because there was a breaking change and you didn't bother to read the CHANGELOG documenting it.

This plugin inherits from ben-manes/gradle-versions-plugin the feature to automatically determine which dependencies have updates.

When you decide you want to update some dependencies, run the plugin again:

The file Versions.kt is regenerated with a comment indicating which new version is available.

At that point, your build is exactly the same. Commit.

Don’t waste your time finding out manually what is the exact latest stable version available. Instead, spend it deciding whether you want or not to update the version. The format is optimized to update with one DELETE key:

Press DELETE to update

This screencast shows this in action:

Once you are done:

  • Sync your Gradle build
  • Run your unit tests and otherwise verify that it works.
  • Commit.

Show me an example! 😽

I submitted a pull-request to dev.to's Android app

Dependencies management with Gradle buildSrcVersions #44

Description

Hello, I refactored the Gradle build to use my plugin buildSrcVersions to manage dependencies.

The files {Libs,Versions}.kt have been generated with the command $ ./gradlew buildSrcVersions

See https://github.com/jmfayard/buildSrcVersions

See this article https://dev.to/jmfayard/better-dependency-management-in-android-studio-3-5-with-gradle-buildsrcversions-34e9

Next Steps

Currently the versions in the dependencies are exactly the same as on master.

If you wish to update Kotlin, edit Versions.kt

If you want to update Gradle, run $ ./gradlew wrapper

New in Android Studio 3.5 🆕 ?

Let me backtrack a bit: the buildSrc is technically not a new thing. Gradle made it available a number of years ago and is widely used in JVM/IntelliJ projects. But it may well be new to you: the IDE integration that makes it a game changer launched in Android Studio 3.2. Without enough publicity. And then it got broken immediately after in Android Studio 3.3 and 3.4 with bug #123032843.

So you are excused if you missed the news, and now is a good time to give it a try.

As a conclusion, I will share my favorite reaction after first posting this story:

References 📚

Github

GitHub logo Splitties / refreshVersions

Life is too short to google for dependencies and versions

What is refreshVersions?

refreshVersions helps Gradle users with the tedious manual work usually involved in adding and updating dependencies and their versions.

Documentation

See documentation at https://splitties.github.io/refreshVersions

Setup

// settings.gradle(.kts)
plugins {
    // See https://splitties.github.io/refreshVersions
    id("de.fayard.refreshVersions") version "0.60.5"
}

refreshVersions { // Optional: configure the plugin
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Read the friendly documentation

Usage

Make sure the project is correctly set up (see just above).

Migrate project:

The refreshVersionsMigrate task can help you migrate your project in a few minutes, or less.

In version 0.50.0, support for Gradle's Versions Catalogs was added (see discussion thread here), so a --mode option is now required.

Run it without it to see the complete list and the full description of…

Top comments (2)

Collapse
 
davidburstromspotify profile image
David Burström

Cool trick! I think it's good to know that when you update a version, this will change the classpath generated by buildSrc which will cause most if not all main build tasks to re-execute. This can be highly counter-productive in larger projects.

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

Which is one of the reason why I just released another solution based on generating dependencies and plug-in versions inside gradle.properties
Have a look here
github.com/jmfayard/buildSrcVersio...