Source: https://developers.woosmap.com/products/mobile/android/gradle-kotlin/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Using Kotlin for Gradle



This guide will show you a step by step process to convert a brand new Android Studio project build scripts to Kotlin.

## Advantages

The default language for Gradle' scripts is **Groovy**, it's a highly dynamic and permissive language which allows you to write the same thing in various ways.
You can write something eye pleasing and *configuration-like* but the drawback is that it's hard to inspect for the IDE.

For example `foo 42` could be a function call (`foo(42)`) or a variable assignment (`foo = 42`) and 42 could be treated as a number or a string.
Because Gradle makes extensive use of plugins you often have to refer to the plugin's documentation to see what's possible.

Switching to **Kotlin** will give you better code inspection and completion making it that much more simple to maintain your build scripts with your project.

Sadly, the current Android Studio (Flamingo 2022.2) only provides project templates with Groovy files.
This guide will show you the necessary steps to convert a brand new project build scripts to use Kotlin.
Here we'll use the `Empty Views Activity` template but the steps are easily adaptable.  

## Switching to Kotlin

Most changes are syntax related, luckily Groovy' syntax can be compatible with that of Kotlin.

Overall switching to Kotlin is applying the same 4 steps process:
- Using Find and Replace to change all `'` (single quote) with `"` (double quote)
- Adding explicit parentheses to function calls and equal signs to assignments
- Renaming the file to add `.kts` at the end
- Fixing the names of variables that differs between Groovy and Kotlin and add some explicit cast (mostly for `uri`)

The second step is the hardest since you don't really have a clear way of knowing which are functions and which are variables beforehand.
So we're going to show this on a concrete example.

## Concrete Example

We have a brand new project from the `Empty Views Activity` template.

Let us start with `settings.gradle` almost all lines are function calls with explicit parentheses and even setting the root project's name use double quotes.
The only line that needs modification is the last one. It needs to be changed from `include ':app'` to `include(":app")`, so we convert the single quotes into double and add the explicit parentheses for the `include` function.

```groovy
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "Woosmap Demo"
include ':app'
```

```kotlin
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "Woosmap Demo"
include(":app")
```

Next we move onto the project's `build.gradle`.
First let's start by using the editor's Find & Replace to change all the single quotes into double.
We then need to add explicit parentheses however in this specific case they are needed only for the `id` function which takes only one String argument.
So a line like `id 'com.android.application' version '8.0.2' apply false` becomes `id("com.android.application") version "8.0.2" apply false`.
That's because both `version` and `apply` are [infix functions](https://kotlinlang.org/docs/functions.html#infix-notation) but you can add parentheses to them both if you wish.  

```groovy
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '8.0.2' apply false
    id 'com.android.library' version '8.0.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
}
```

```kotlin
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id("com.android.application") version "8.0.2" apply false
    id("com.android.library") version "8.0.2" apply false
    id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}
```

Last but not least we take on the module-level `build.gradle` of the app.
Again use Find & Replace to change single quotes in double.

The first block is `plugins` which is the same as the one we saw just before in the project's `build.gradle`.
So do the same and add explicit parentheses for the `id` functions.
At the end of the file you should have a `dependencies` block, it only contains function calls so add explicit parentheses to `implementation`, `testImplementation` and `androidTestImplementation`.

Finally for the `android` block and sub-blocks almost everything are variables assignments, add explicit `=` equal sign to everything.
**EXCEPT** for the `proguardFiles`, by default it's the only function call there is in this example hence it needs explicit parentheses around all arguments.
The last line that needs modification is `minifyEnabled false`, most boolean flags with the Kotlin plugin's interface exist with the prefix `is`, so change it to `isMinifyEnabled = false`.

```groovy
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.woosmapdemo'
    compileSdk 33

    defaultConfig {
        applicationId "com.example.woosmapdemo"
        minSdk 27
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.10.1'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
```

```kotlin
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.woosmapdemo"
    compileSdk = 33

    defaultConfig {
        applicationId = "com.example.woosmapdemo"
        minSdk = 27
        targetSdk = 33
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.10.1")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.9.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
```

Now that all our files are changed we need to add `.kts` to theirs filenames in order for Android Studio and Gradle to interpret them using Kotlin.
Renaming them while Android Studio is open might cause problem, so it's better to close it completely before renaming all files and then reopen it so it can start fresh.
