Migrating to the Kotlin buildscript

To explore the Gradle Kotlin DSL, we're going to migrate our existing Android project to make use of the DSL.

The first step will be to go through both of our build.gradle files and ensure that all string literals are using double quotes (") instead of single quotes (') and that all Gradle function calls are using parentheses. 

In the case of the top-level build.gradle file, this means adding parentheses to the classpath() function calls. This is required because Groovy allows you to omit these parentheses, whereas Kotlin requires them to be used. The following code demonstrates what this update looks like in our project-level build.gradle file:

// root-level build.gradle
buildscript
{
ext.kotlin_version = "1.3.31"
repositories {
google()
jcenter()
}

dependencies {
// addition of ( ) when using classpath function
classpath("com.android.tools.build:gradle:3.5.0-beta04")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}

...

The next step will be to rename each build.gradle file by adding .kts to the end so that the full filename is build.gradle.kts. This will indicate that the file is using the Kotlin Gradle DSL.

Once these filenames have been updated, we will have several errors to address. We will start by updating the root-level build.gradle.kts file.

First, we'll update the definition of the existing clean task as follows:

task(name = "clean", type = Delete::class) {
delete(rootProject.buildDir)
}

Notice that we're able to make use of named parameters to define our invocation of the task function.

Next, we'll update our kotlin_version extension and its usage in declaring the Gradle Kotlin plugin. Consider the following code:

buildscript {
extensions.add("kotlin_version", "1.3.31")
repositories {
google()
jcenter()
}

dependencies {
classpath("com.android.tools.build:gradle:3.5.0-beta04")
// using extensions.get() to retrieve Kotlin version
classpath ("org.jetbrains.kotlin:kotlin-gradle-
plugin:
${extensions.get("kotlin_version")}")

}
}

We can define and retrieve extensions using extensions.add() or extensions.get(). Later on, we'll explore another means of defining our dependencies that doesn't rely on extensions.

Now, let's jump over to the app module's build.gradle.kts file. We'll start by updating the plugin declarations using the plugins block:

plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
}

Next, we'll update our Android configuration block as follows:

android {
compileSdkVersion(28)
defaultConfig {
applicationId = "com.goobar.hellokotlin"
minSdkVersion(21)
targetSdkVersion(28)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner =
"androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile(
"proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}

And lastly, we'll update our dependencies block:

dependencies {

implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31")

implementation("androidx.appcompat:appcompat:1.0.2")
implementation("androidx.core:core-ktx:1.0.2")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
testImplementation("junit:junit:4.12")
androidTestImplementation("androidx.test.ext:junit:1.1.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
}

At this point, our Gradle build is now using the Gradle Kotlin DSL. This gives us the familiar syntax and features of Kotlin when working with Gradle.