Migrating to Kotlin DSL & Version Catalog
A step-by-step guide for a stress-free migration
With the release of Android Studio Giraffe, Kotlin DSL became the default Gradle build scripts in Android development, as it offers more readable code, compile-time checking and IDE support.
Migrating from your old Groovy DSL projects may seem daunting, but in this step-by-step guide we'll go through everything that needs to be changed, ensuring a stress-free migration.
We'll also take a look at Version Catalog, a powerful way to keep all your dependencies organized.
Migrating to Kotlin DSL
Identify Files to Convert
Whether your project is the classic single-module, or a multi-module one, identifying our groovy-based Gradle files, that we want to convert, is the first step.
Typically, every project has a settings.gradle
, the project level build.gradle
, and module level build.gradle
files. Additional gradle files also need converting.
Convert the Syntax
One of the main differences from Groovy to Kotlin is the syntax. Before changing the script file name, apply these changes throughout your build files:
Use double quotes for strings
While Groovy lets you use single quotes to define strings, Kotlin requires double quotes.
The following example in Groovy:implementation 're.notifica:notificare:3.6.1'
should be changed to:
implementation "re.notifica:notificare:3.6.1"
💡 Pro Tip: Finding all usages of
'
and replacing them for"
makes this job much easier!Add parenthesis to method calls
While Groovy lets you omit parenthesis, Kotlin methods require them.
So, back to the previous example, from Groovy:implementation "re.notifica:notificare:3.6.1"
to Kotlin:
implementation("re.notifica:notificare:3.6.1")
Add
=
to assignment calls
While Groovy lets you omit the assigment operator, Kotlin requires them.
Take the following example from Groovy:applicationId "re.notifica.go"
In Kotlin:
applicationId = "re.notifica.go"
Define variables the Kotlin way
Replace the Groovy variable keyworddef
with the Kotlin keywordsval
orvar
. From Groovy:def notificare_version = "3.6.1"
To Kotlin:
val notificare_version = "3.6.1"
Prefix Booleans
Groovy deducts methods based on the property names. In Kotlin, however, we need to change the property names to the non-supported deduced methods. In thebuildTypes
DSL, for example:android { buildTypes { release { minifyEnabled true ... } ...
Boolean properties should be prefixed with
is
android { buildTypes { getByName("release") { isMinifyEnabled = true ... } ...
We recommend you start with your simplest files first, and, after some practice, go through the more complex ones.
Rename Script Files
By now, all general changes were made, so you can start renaming you .gradle
file extensions to .gradle.kts
.
However, you may notice that changes specific to each file still need to be made.
Clean Task on the Project Level Build File
Every project level build file has a clean task.
You might notice that after changing the file extension to .gradle.kts
, Android Studio marks the old usage as an error.
Kotlin does things differently. From the old Groovy syntax:
task clean(type: Delete) {
delete rootProject.buildDir
}
To the new Kotlin one:
tasks.register("clean",Delete::class){
delete(rootProject.buildDir)
}
You should also take this opportunity to resolve the deprecated getter for the build directory. Instead of:
rootProject.buildDir
do:
rootProject.layout.buildDirectory
Configure Build Types
You might have noticed in a previous example, that made use of the buildTypes
DSL, that things were a little different.
In Kotlin, build types must be one of the default, such as release
and debug
, accessed by the getByName(buildType)
method, or a new one created using the create(buildType)
method.
As such, what would be the norm in Groovy:
buildTypes {
debug {
...
}
release {
...
}
benchmark {
...
}
}
Is now, in Kotlin:
buildTypes {
getByName("debug") {
...
}
getByName("release") {
...
}
create("benchmark") {
...
}
}
If you're wondering how this changes the signinConfigs
block, fear not. The conversion is the same.
However, only the debug
configuration comes by default, meaning you have to create the remaining ones.
Additional Conversions
Every project is different. Therefore, different functionalities may be present in yours. If any of those functionalities are not covered in this guide, we recommend taking a look at both migration guides from Google and Gradle.
Version Catalog
Another new Gradle functionality that greatly improves maintainability of your project dependencies and plugins is the Version Catalog. Especially in multi-module projects, declaring or upgrading a dependency can be a hassle, looking for all hardcoded usages and maintaining consistent versioning throughout every individual build file.
To make this process easier, you can create a central Version Catalog that all your build files can reference.
Creating a Version Catalog File
In your project's gradle
folder, start by creating a file called libs.versions.toml
.
Here, we define 3 categories, as such:
[versions]
[libraries]
[plugins]
Migrate Your Dependencies
With your file set up, you can start migrating your old dependency declarations into your central catalog.
A dependency on your build.gradle.kts
file:
dependencies {
implementation("re.notifica:notificare:3.6.1")
}
Can be cataloged as such:
[versions]
notificare = "3.6.1"
[libraries]
notificare = { module = "re.notifica:notificare", version.ref = "notificare" }
and declared in your build.gradle.kts
:
dependencies {
implementation(libs.notificare)
}
Additionally, you can declare groups of dependencies often used together as a bundle
, minimizing declarations on your build.gradle.kts
file, as such:
[bundles]
notificare-geo = ["notificare-geo", "notificare-geo-gms", "notificare-geo-beacons"]
dependencies {
implementation(libs.bundles.notificare.geo)
}
Migrate Your Plugins
Migrating your plugin declarations is relatively similar to migrating your dependencies, with a few caveats.
The declaration should be done in the plugins
category of your version catalog and use the alias
keyword in your build file, like so:
[versions]
kotlin = "1.9.1"
[plugins]
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
plugins {
alias(libs.plugins.kotlin.android)
}
That's it. You now have a central catalog for all your dependencies. The next time you have to update your dependencies, changing a single file sure makes the job easier!
Conclusion
In this blog post, we guided you through the migration process to Kotlin DSL and to a centralized Version Catalog. With Kotlin DSL, you can expect a better editing experience, and with a central version catalog, maintain coherent versioning throughout your project. Adopting these build technologies promotes the readability and scalability of your project build files, ensuring easy and stress-free maintenance.
As always, we hope you liked this article, and if you have anything to add, we are available via our Support Channel.