Static Code Analysis Tools for Kotlin in Android
In this article we will learn how to include a static analysis tool (Detekt) for a multi module Android Kotlin project, we also are going to learn how we can set it up to apply a set of rules to check the style, code smells, etc.
Note: this article is outdated, please check my last post about how to configure the last Detekt version.
Back in 2017 I wrote about how to configure Detekt for an Android multi-module project:medium.com
Probably you are familiar with some kind of static analysis tool, basically these tools check our code without actually executing it, they look for code smells, possible memory leaks, they measure the cohesion and dependencies between classes or identify style incoherencies.
This labor is critical to maintain a good foundation in our code, and to keep the whole team in the same page.
For Java there are plenty: pmd, findbugs, checkstyle, SonarQube, just to name a few, but in Kotlin the choice is not that wide, so far I have been able to find two meaningfully options: Detekt and Ktlint, I personally don’t like Ktlint since its rules cannot be modified and the existing Gradle plugins are not easy to integrate, on the other hand, Detekt, works pretty fine, its plugin is still a bit too new, but its a promising option.
Detekt gives us several interesting metrics:
- Code smells.
- Complexity report.
- Code style check.
The tool writes a report using the console, which looks like this:
But also it can beconfigured to write the output in different files: plain text or xml.
Detekt performs its analysis based on a set of rules we can configure in a .yml file, for instance we can define the error threshold to break the build, enable or disable rules, enable or disable auto editing options, etc.
This configuration is done by using a closure that we can define in an external file, which looks like this:
It can be configured to work different for each submodule inside a project using Gradle profiles, which give us the opportunity to apply different set of rules to a different submodules.
To know more about the properties that we can define please visit its GitHub page (you can find it in references).
In Android its integration is not the most desirable so far. What I am going to show is the best I was able to do in a multi module project, any other alternative I tried gave me different sort of problems, so here we are, if you find out a different way, please leave a comment.
First in the project.build level you have to add:
But this will apply the check in all modules, and we don’t want this. We want to select in which modules we want to run the check. The standard way to go in this case would be to add `apply false` which disable this behaviour, and later on selectively choose in which modules we want to apply the plugin, but this does not work properly with Detekt in Android yet, so we have to manually add the plugin to each build.gradle in each module, it’s not pretty, I know.
plugins is an experimental feature, so for example we cannot extract the version into an external file :(
Now we want to load the configuration for Detekt inside each module, as we mentioned before we use a closure for this purpose, and we can write it directly inside the build.gradle or extract it into a separate file and reference it inside de build.gradle in the following way:
apply from: ‘../detekt.gradle’
Remember, inside this file we must include the closure.
And now, to run the tool just type :
The console will show you a report with several metrics.
Happy checking :).
Thanks to @aconsuegra for reviewing this post.