DEV Community

CharlieTap
CharlieTap

Posted on • Updated on

Upgrading to Gradles modern plugin configuration

Android studio Bumblebee became stable this week and with it comes a bunch of new features and updates. One of which being that new projects created in Bumblebee have a modernised Gradle configuration. You can read about this here

Whilst this is great for new projects, it's important to keep legacy projects up to date, and migrating from old to new is great way to understand the new approach (I say "new" here, but the syntax has in fact been around for quite some now, it just hadn't been widely adopted).

Why Upgrade?

A quick scan of the Gradle docs goes on to explain the following:

Image description

Alongside this, generally its good to keep your configuration compliant with the latest version of Gradle, it eases the migration path when moving between versions.

How did we used to do it again?

Historically Android projects would use the buildscript DSL to load load plugins into the classpath, you would do this is your top level build.gradle file.

It should look something like this:

build.gradle

buildscript {

    repositories {
        google()
        gradlePluginPortal()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:x.y.z'
        classpath "org.jetbrains.kotlin:kotlin-gradle-pluginx.y.z"
    }
}

Enter fullscreen mode Exit fullscreen mode

Theres two things happening inside this block:

  1. It's declaring a set of repositories, these are repositories which will be searched when Gradle looks for the plugins you have declared. This is similar to the list of repositories you declare when you are configuration your dependencies, however these repositories will only be searched when Gradle looks for plugins.

  2. It's declaring a set of plugins you wish to use in your project and loading a particular version for each into the classpath.

Applying the plugins in your application

Inside your :app modules build.gradle you would use the now legacy apply plugin syntax to enable the plugins on that particular module.

app/build.gradle


apply plugin: 'com.android.application'

Enter fullscreen mode Exit fullscreen mode

If you've ever worked on projects that have more than one Gradle module you realise the benefits of the separation above as you'll be able to enable plugins on a module by module basis, and lock the plugin versions to a consistent version across all of your modules.

Okay but what does it look like now

Well, the part where you declared the repositories for the plugins... that's moved, its now in your top level settings.gradle file

settings.gradle


pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

Enter fullscreen mode Exit fullscreen mode

This makes more sense when you realise the repositories for your dependencies are also now moved the settings.gradle file

settings.gradle


dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

Enter fullscreen mode Exit fullscreen mode

Loading the plugins

Loading the plugins (but not applying them), still takes place in the top level build.gradle file

build.gradle

plugins {
    id 'com.android.application' version 'x.y.z' apply false
    id 'org.jetbrains.kotlin.android' version 'x.y.z' apply false
}

Enter fullscreen mode Exit fullscreen mode

Enabling the plugins

This takes place in whatever module you want to apply the plugin on, for example:

app/build.gradle


plugins {
    id('com.android.application')
    id('org.jetbrains.kotlin.android')

}

Enter fullscreen mode Exit fullscreen mode

Thats all?

Well as with everything new, there's some gotchas here to be aware of. The most important of which is that not all plugins will work the new syntax.

Notice how before you would say something like:

apply plugin: 'kotlin-android'
Enter fullscreen mode Exit fullscreen mode

and now you say something like:

id('org.jetbrains.kotlin.android')
Enter fullscreen mode Exit fullscreen mode

The difference is the latter uses a particular id, and only plugins which are configured with Gradle Project Market Artifact will work out of the box with this syntax.

In particular I have found one popular plugin at this time which is not compliant and that is the Dagger Hilt Plugin.
You can track the support for it here, it's quite likely by the time you read this post that it will already have been released.

Is there any point if not all plugins work

Well there's a workaround, and for the plugins you do configure, you'll theoretically optimise your build time by adopting those.

Workaround

We'll use the case of Dagger as I imagine this to be the most common. For future proofing I have put the future syntax, commented out in the examples below.

Put the following in your top level build.gradle

build.gradle


// it will look like this once Dagger publishes the marker
// id 'com.google.dagger.hilt.android' version 'x.y.z' apply false

// for now
id("dagger.hilt.android.plugin") apply false

Enter fullscreen mode Exit fullscreen mode

Then in your settings.gradle the following:

settings.gradle


pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if( requested.id.id == 'dagger.hilt.android.plugin') {
                useModule("com.google.dagger:hilt-android-gradle-plugin:x.y.z")
            }
        }
... repository management config
}

Enter fullscreen mode Exit fullscreen mode

Finally apply the plugin in your app modules build.gradle

app/build.gradle


plugins {
//  id 'com.google.dagger.hilt.android' in the future
    id 'dagger.hilt.android.plugin'
}

Enter fullscreen mode Exit fullscreen mode

The above solution should work for any legacy Gradle plugin which lacks the marker you need.

Cool, so anything else?

This is the first in a three post series, the following two will cover:

  • Integration of the new plugin system and Gradles' new version catalog system, you can find it here

  • Creating your own pre compiled script plugins for tidying up your build.gradle config and give an example showcasing config for the popular the popular versions gradle plugin

Top comments (0)