Supercharge your Kotlin Project
Tags: android, computerscience, kotlin, programming
Published: 2021-10-20 15:02:12

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:paragraph -->
<p>This article shares some tips on things to include inside your kotlin project. We will cover briefly:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Ktlint</li><li>Detekt</li><li>Github workflow</li></ol>
<!-- /wp:list -->

{% youtube NIuslCdkn8Y %}

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: This article assumes the reader knows about Kotlin</p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading {"level":3} -->
<h3>Ktlint</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Linting is the process of analyzing code for potential errors and one of the ways we can do that in Kotlin is using <a href="https://ktlint.github.io/" rel="noreferrer noopener" target="_blank"><strong>Ktlint</strong></a>. As per the documentation:</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://ktlint.github.io/" rel="noreferrer noopener" target="_blank"><strong>Ktlint</strong></a> is an anti-bikeshedding Kotlin linter</p></blockquote>
<!-- /wp:quote -->

{% youtube JZsJln3Cl4U %}

<!-- wp:paragraph -->
<p>There are two ways to integrate Ktlint in a kotlin project.&nbsp;</p>
<!-- /wp:paragraph -->

```kotlin
jlleitschuh/ktlint-gradle
jeremymailen/kotlinter-gradle
```

<!-- wp:paragraph -->
<p>We will be using <a href="https://github.com/JLLeitschuh/ktlint-gradle" rel="noreferrer noopener" target="_blank">ktlint-gradle</a>, which is a wrapper over ktlint.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Setup</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>Head over to the project-level <a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></li><li>Inside the <code>buildscripts</code> add the latest version in <code>ext</code> and add the dependency under <code>dependencies</code></li></ul>
<!-- /wp:list -->

```groovy
ext {
   // https://github.com/JLLeitschuh/ktlint-gradle/releases
   ktlintPluginVersion = "10.2.0"
}
dependencies {
    classpath 'com.android.tools.build:gradle:7.0.0'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32"
    
    ## KTLINT DEPENDENCY
    classpath "org.jlleitschuh.gradle:ktlint-gradle:$ktlintPluginVersion"    
}
```

<!-- wp:paragraph -->
<p>Inside the <code>repositories</code> section, add this</p>
<!-- /wp:paragraph -->


```groovy
repositories {
    google()
    mavenCentral()
    ## ADDED THIS FOR KTLINT
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}
```

<!-- wp:paragraph -->
<p>We create a separate file for configuring/customizing <code>ktlint</code>. Create a directory <code>buildscripts</code>at the project level and inside it, create a new file called <code><a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/buildscripts/ktlint.gradle" rel="noreferrer noopener" target="_blank">ktlint.gradle</a></code></p>
<!-- /wp:paragraph -->

```groovy
apply plugin: "org.jlleitschuh.gradle.ktlint"
ktlint {
    // https://github.com/pinterest/ktlint/releases
    version = "0.42.1"
    reporters {
        reporter "plain"
        reporter "checkstyle"
        reporter "html"
    }
    outputColorName = "RED"
}
```

<!-- wp:paragraph -->
<p>Finally, we apply this configuration to all our <code>subprojects</code> by adding the below inside our project-level <a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></p>
<!-- /wp:paragraph -->

```groovy
subprojects {
    apply from: "../buildscripts/ktlint.gradle"
}
```

<!-- wp:list -->
<ul><li>Click <code>Sync Now</code> If everything is successful, we should see a gradle task called <code>ktlintformat</code>&nbsp;</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*WnYNJ1vGKehpDZqrmFXgyw.png" alt="ktlintFormat Gradle task"/><figcaption>ktlintFormat Gradle&nbsp;task</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: In case you are not able to see your gradle tasks, check this <a href="https://programmerah.com/gradle-tasks-disappeared-after-upgrading-android-stuido-4-2-29098/" rel="noreferrer noopener" target="_blank">post</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>After running the task <code>ktlintformat</code> it outputs the results, (in case of errors, it will show the file which has the details of the files)</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*zsPB0DYfRaEFBxnMve9Dtg.png" alt="ktlintformat errors"/><figcaption>ktlintformat errors</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Click on the&nbsp;<code>.txt</code> file and correct the errors accordingly.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: You will probably have a lot of file changes, since <code>ktlintformat</code> checks all your project files and corrects them as per the kotlin standard.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading {"level":3} -->
<h3>Detekt</h3>
<!-- /wp:heading -->

{% youtube 2ACLWbLzWGg %}

<!-- wp:paragraph -->
<p><a href="https://github.com/detekt/detekt" rel="noreferrer noopener" target="_blank">Detekt</a> is a static code analysis tool for the <em>Kotlin</em> programming language. It operates on the abstract syntax tree provided by the Kotlin compiler.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It analyzes the Kotlin code with multiple rule sets and flags the code that breaks any of its rules.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Setup</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>Head over to the project-level <a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></li><li>Inside the <code>buildscripts</code> add the latest version in <code>ext</code> and add the dependency under <code>dependencies</code></li></ul>
<!-- /wp:list -->

```groovy
ext {
   // https://github.com/detekt/detekt/releases
   detektVersion = "1.17.0"
}
dependencies {
    classpath 'com.android.tools.build:gradle:7.0.0'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32"
  
    ## DETEKT DEPENDENCY
    classpath "io.gitlab.arturbosch.detekt:detekt-gradle-    plugin:$detektVersion"  
}
```

<!-- wp:paragraph -->
<p>We create a separate file for configuring/customizing <code>detekt</code>. Create a directory <code>buildscripts</code>at the project level (ignore if you created in the above step) and inside it, create a new file called <code><a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/buildscripts/detekt.gradle" rel="noreferrer noopener" target="_blank">detekt.gradle</a></code></p>
<!-- /wp:paragraph -->

```groovy
apply plugin: "io.gitlab.arturbosch.detekt"

detekt {
    config = files("${rootProject.projectDir}/config/detekt/detekt.yml")

    reports {
        html.enabled = true
        xml.enabled = true
        txt.enabled = true
    }
}
```

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: The config file <code>detekt.yml</code> doesn’t exist yet, we will see in the later step</p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>Finally, we apply this configuration to all our <code>subprojects</code> by adding the below inside our project-level <a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></li></ul>
<!-- /wp:list -->

```groovy
subprojects {
    apply from: "../buildscripts/detekt.gradle"
}
```

<!-- wp:list -->
<ul><li>Click <code>Sync Now</code> If everything is successful, we should see a gradle task called <code>detektGenerateConfig</code> and run it</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*umyJODh2sYWfrV1fBhijbw.png" alt="detekt generateConfig gradle task"/><figcaption>detekt generateConfig gradle&nbsp;task</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:list -->
<ul><li>After running the task, it generates the config file called <code>detekt.yml</code>&nbsp;</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*FU1_dEdG0d-Loq1nfDyj6g.png" alt="detekt config yml"/><figcaption>detekt config&nbsp;yml</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>which comprises of all the configurations, detekt comes with. We can customize it according to our preference.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Finally, we run the following in our project</li></ul>
<!-- /wp:list -->

```groovy
./gradlew detekt
```

<!-- wp:paragraph -->
<p>This will show you all the issues inside your project, along with the configuration name.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*Hh5rG3JD8BaO64mxnHNO1Q.png" alt="detekt issues in project"/><figcaption>detekt issues in&nbsp;project</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In case, you want to suppress some issue in a file, for instance, the above issues related to <code>MagicNumber</code> , we can simply go to the file and add</p>
<!-- /wp:paragraph -->

```kotlin
@file:Suppress("MagicNumber")
```

<!-- wp:heading {"level":3} -->
<h3>Github workflow</h3>
<!-- /wp:heading -->

{% youtube 2s3Aaf3s_xU %}

<!-- wp:paragraph -->
<p>We saw in the above steps how to integrate <code>ktlint</code> and <code>detekt</code> inside our kotlin project.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the last step, we will integrate both with our CI, ensuring the main branch, always remains standardized.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Add a <code>.github</code> directory inside the project.</li><li>Create a subdirectory <code>workflows</code> and inside it, create a file called <code><a href="https://github.com/AseemWangoo/hands_on_kotlin/blob/master/.github/workflows/android_build.yml" rel="noreferrer noopener" target="_blank">android_build.yml</a></code> </li></ul>
<!-- /wp:list -->

```yml
name: Android Build

on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Set Up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11

      - name: Build Project
        run: ./gradlew assemble

      - name: Run Tests
        run: ./gradlew test

      - name: Lint Checks
        run: ./gradlew ktlintCheck detekt
```

<!-- wp:list -->
<ul><li>In the last step, we include the <code>ktlintCheck</code> as well as <code>detekt</code> Since this job runs on push, we will be sure in case the code is according to our conventions.</li><li>We can also add a branch protection rule for requiring status checks to pass and selecting <code>build</code></li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*LTwmzsXI-UJrp7xyv27R2A.png" alt="Branch protection rule"/><figcaption>Branch protection rule</figcaption></figure></div>
<!-- /wp:image -->

{% youtube NIuslCdkn8Y %}

<!-- wp:paragraph -->
<p><a rel="noreferrer noopener" href="https://github.com/AseemWangoo/hands_on_kotlin" target="_blank"><em>Source code.</em></a>

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>